Due to security reasons, JavaScript/AngularJS does not allow the loading of local files when running the app locally, off of your desktop. You must either have a localhost instance or run the whole thing from a web server.
In my case, I'd like to place the entire angular app in an eBook implementation. So, I do need to be able to run it as if it is on the desktop.
An alternative way to load the templates is to use the script id tag. In that case, template content is hardcoded in the index.html or the app.js.
But not exactly sure how to go about it?
How do we convert the following config code to script ID based implementation? And while I'm at it, let me also throw in this question as well; Are there any disadvantages of choosing this approach - other than the obvious modularity ( code organization )?
Here is the code that needs to be converted to id based approach.
I'm not sure how to convert the "resolve", "controllerAs" information thru the script-id based implementation.
angular.module("quickquiz").config(["$routeProvider", "$mdThemingProvider", function ($routeProvider, $mdThemingProvider) {
$mdThemingProvider.theme('default')
$routeProvider
.when("/home", {
templateUrl: 'templates/home.html',
controller: 'HomeController',
controllerAs: 'home',
resolve: {
quizConfig: ["QuizConfig", function (QuizConfig) {
return QuizConfig.loadConfig();
}],
quizStorage: ["QuizStorage", function (QuizStorage) {
return QuizStorage.loadQuizes();
}]
}
})
.when("/:currentPage", {
templateUrl: 'templates/main.html',
controller: 'MainQuizController',
controllerAs: 'main',
resolve: {
quizConfig: ["QuizConfig", function (QuizConfig) {
return QuizConfig.loadConfig();
}],
quizStorage: ["QuizStorage", function (QuizStorage) {
return QuizStorage.loadQuizes();
}]
}
})
.when("/:1", {
templateUrl: 'templates/main.html',
controller: 'MainQuizController',
controllerAs: 'main',
resolve: {
quizConfig: ["QuizConfig", function (QuizConfig) {
return QuizConfig.loadConfig();
}],
quizStorage: ["QuizStorage", function (QuizStorage) {
return QuizStorage.loadQuizes();
}]
}
})
.otherwise("/home");
}]
);
I know that the solution to my problem pass thru an implementation as follows; but again, not exactly sure how to deal with those "resolve" portion here;
[script type="text/ng-template" id="/tpl.html"] Content of the
template. [/script]
source: https://docs.angularjs.org/api/ng/directive/script
You can load templates directly into the cache in a script tag, or by consuming the $templateCache service directly. $templateCache.
Related
I have an Angular app which has several dynamic fields, each of these fields are changed updated based on config which comes from a backend database.
In order to control what config is used I need to dynamically switch a single variable - I've decided that the URL is the best way to set/switch the variable as there need to be multiple permutations of the site based on the URL so:-
/:dynamicVariable/
I'm looking for some guidance as to whether this is the best way to do it and what the best way to do it would be? I'm struggling as I don't want to have to set each route for each section like this /:dynamicVariable/homepage /:dynamicVariable/about-us etc etc. Ideally the core module checks it and sets it but the routing ignores it so /:dynamicVariable/ becomes the root.
Hope that makes sense, thanks in advance for your help.
I ended up doing this by using ui.router and nesting states within an abstract parent state which held the client, like so :-
.state('rootClient', {
abstract: true,
url: '/:client',
templateUrl: 'app/layout/layout.html',
controller: 'Layout',
controllerAs: 'layout',
noClient: false,
resolve: {
client: function ($stateParams, ClientService) {
return ClientService.getClient($stateParams.client);
}
}
})
.state('rootClient.home', {
url: '/homepage',
views: {
'content': {
templateUrl: 'app/homepage/homepage.html',
controller: 'Homepage',
controllerAs: 'home'
}
}
});
This way all the routes are under the parent route, I also added a resolve to make sure the client exists before moving to the route. Hopefully this will help someone else down the line.
Cheers
So, the workflow with angularjs $routeProvider goes as following,
$routeProvider
.when('/main1', {
templateUrl: 'view1.html',
})
.when('/main2', {
templateUrl: 'view2.html',
})
My question is, is there any way of simplifying the following code. If when('/main1') and when('/main2') point to the same template. So,
$routeProvider
.when('/main1', {
templateUrl: 'view1.html',
})
.when('/main2', {
templateUrl: 'view1.html',
})
The question is asked because if we have multiple languages on the site, and we want to have multiple translations of the url.
Another solution would be to recognize if the site is using .com or .de for instance, and thus adjust to the correct /main1 or /main2 translation. So for instance,
var url = window.location.href;
var main;
if (url.match(/.de/) !== null){
main = "/main1";
}else{
main = "/main2";
}
$routeProvider
.when(main, {
templateUrl: 'view1.html',
})
But semantically, this doesn't seem to be the best solution as I like to keep configuration options set in the run block after the config. We also can't inject factories (only providers, I may be mistaken though) to config.
I would go for putting the language as first url segment in the route.
$routeProvider.when('/:lng/main', {
templateUrl: 'main.html',
controller: function($routeParams){
var lng = $routeParams.lng;
}
})
Though it would be really nice if the $routeProvider would provide this functionality where the an url segment can be isolated. I ain't that pretty putting :lng in each route.
I need to change an existing AngularJS application from using URLs in the format:
example.com/thePage/#/section/1/subsection/1
To making the section & subsection parameters readable by the server with a format like so:
example.com/thePage?section=1&subsection=1
The environment does not offer something like mod_rewrite, so I need to change the routing in Angular to make it handle & generate these URLs. I believe I can do this using $locationProvider.html5Mode(true); however I’m not sure how to proceed from there. I’ve tried updating the existing routing to something like the below, however it fails to return a view (as if the routing isn’t working.
$stateProvider
.state('section', {
abstract: true,
url: '?section',
views: {
'header': {
template: '<h3></h3>'
},
'main': {
templateUrl: constants.baseUrl + 'views/section.html',
controller: 'sectionCtrl',
resolve: {
section: ['sectionervice', '$stateParams',
function (sectionervice, $stateParams) {
return sectionervice.getsection($stateParams);
}],
subsection: ['sectionervice', '$stateParams',
function (sectionervice, $stateParams) {
return sectionervice.getsubsection($stateParams);
}]
}
}
}
})
.state('section.detail.subsection', {
url: '&subsection=:sectionId',
views: {
'main': {
templateUrl: constants.baseUrl + 'views/section.detail.subsection.html',
controller: 'DictionaryCtrl'
}
}
});
It seems that $stateProvider may only work with the forward-slash(/) parameter delimiter. Is there another way to achieve this?
In the ui-router website has a simple example of you trying to do.
Maybe you can do the same thing, see the RouteProvider and StateProvider settings.
url: http://angular-ui.github.io/ui-router/sample/app/app.js
In the server side you can retrieve the url, so you can get your parameters.
[Edit]
About $locationProvider.html5Mode(true); you can do this and do the settings in route and state providers too, that don't interfere in functionality
I have a challenge with nested routes, in angular js, here is snippet in app.js
...
when('/profile/:id', {
templateUrl: 'partials/profile',
controller: 'profileCtrl'
}).
when('/profile/:id/editTaskList', {
templateUrl: 'partials/editTaskList',
controller: 'checkListCtrl',
activeMenu: 'editTaskList'
}).
...
I want to have to access to the "profile data" in every single route under the "/profile/:id".
"Profile Data" example is :
{
user: "demo",
title: "dev"
}
and it comes through AJAX(JSON) based on the ID in the routs
The way how it is setup now, is having a service to get the User profile and I make the service request for the profile ID in "profileCtrl".
The problem that I have, if someone share the url and goes right away to "/profile/:id/editTaskList", the "profileCtrl" doesn't fire .
I don't think by adding service request in "checkListCtrl" is a good practice , because I'll have more nested routes under the "profile" and it will require to duplicate the code in multiple controllers.
What is the best practice to fix this issue ? For me would work as well if i can fire "profileCtrl" all the time when we are "/profile/:id" or lower
you can get your data before you controllers are initalized
...
when('/profile/:id', {
templateUrl: 'partials/profile',
controller: 'profileCtrl',
resolve: {
profile: ['ProfileService','$route', function (ProfileService,$route) {
return ProfileService.getProfile($route.current.params.id);
}]
},
}).
when('/profile/:id/editTaskList', {
templateUrl: 'partials/editTaskList',
controller: 'checkListCtrl',
resolve: {
profile: ['ProfileService','$route', function (ProfileService,$route) {
return ProfileService.getProfile($route.current.params.id);
}]
},
activeMenu: 'editTaskList'
}).
...
controller will be
function myCtrl($scope,profile){
// now profile is your data
}
I'm probably just missing something simple, but I want to alias my routes. I am trying to get the route /hello_world to just forward to the existing route of /posttemplate. I want to be able to alias my routes like this to give users and easy to remember way to get to dynamic links... Like Permalinks in blogs. Also, this is sort of a separate question, does anyone know of a good way in angular to define all these routes in a json file or xml or something that will keep this clean as I add many routes to it?
application.config(['$routeProvider', '$locationProvider', function AppConfig($routeProvider, $locationProvider, $routeParams) {
$locationProvider.html5Mode(true).hashPrefix('!');
$routeProvider.when("/dashboard", {
controller: 'controllers.DashboardController',
templateUrl: 'templates/dashboard.html'
}).when("/wishlist", {
controller: 'controllers.WishlistController',
templateUrl: 'templates/wishlist.html'
}).when("/login", {
controller: 'controllers.LoginController',
templateUrl: 'templates/login.html'
}).when("/posttemplate", {
controller: 'controllers.PostTemplateController',
templateUrl: 'templates/posttemplate.html'
}).when("/hello_world", {
controller: 'DynamicRouteController',
templateUrl: function(params){ return '/posttemplate?id=1' }
}).otherwise({
controller: 'controllers.HomeController',
templateUrl: 'templates/home.html'
});
}]);
I think you should first plan your URL patterns carefully. It seems not a good idea to have /{{post_name}} and /posttemplate at the same level.
Maybe you could try to add a path prefix to all your individual articles, like /post/:post_name.
Then you can just add this to your router config:
.when("/post/:post_name", {
controller: 'DynamicRouteController',
templateUrl: 'templates/posttemplate.html'
}
Then in DynamicRouteController, read post_name from $routeParams and map it to your post IDs. You may add something like a unique_name field to your posts, in which stores the URL (/post/post_name) you want it to be accessible from.
Or, if you really want, you can also put them the same level. Just make sure that the "catch-all" item is at the end of your router configs.
And, if you want, you can definitely save the router configs into a JSON file. Just iterate over an array of config items and pass them to when().
You can use redirectTo to redirect from an "alias" to some other route.
.when("/hello_world", {
redirectTo: '/posttemplate'
}
See the docs on $routeProvider for more info.
Well... Here is what I ended up doing... If anyone knows a better way... just let me know.
routes["/dashboard"] = {
controller: 'controllers.DashboardController',
templateUrl: 'templates/dashboard.html',
aliases: ['/dash','/dasher'],
meta: {
title: "Dashboard",
description: 'This is my description'
}
};
routes["/bucket"] = {
controller: 'controllers.PostTemplateController',
templateUrl: 'templates/posttemplate.html',
aliases: [],
arguments: {
id: 1
},
meta: {
title: "Dashboard",
description: 'This is my description'
}
};
//Incontroller
if (!postId)
postId = $route.current.arguments.id;
Check out this project ui-router. It provides several features to enhance your route and template management.