Is it possible to access a provider that would normally be used in a config from a service? The reason for doing so is I don't have the information I need yet to be able to do it in the module.config.
The provider I would like to access is the $stateProvider which is part of the ui.router module. Lets say I have a module that is dependent on other modules. I would like to be able to have these dependencies register their "desired" routes/states with a service and then use the service determine which ones I actually register. I was hoping that this wouldn't have to be done in the config since I would effectively only be adding new states, not removing or modified those that are already there. So basically, I want my service to get a list of states/routes and have the service register them rather than doing it in the config.
As commented:
You won't be able to inject a provider after the config phase. However you can inject during the config phase and store the it somewhere until you need it.
For example
app.config(function($stateProvider) {
window.stateProvider = $stateProvider;
});
app.service('myService', function() {
var $stateProvider = window.state provider;
// ...
});
Disclaimer(s)
Though I am suggesting this as a possibility, I am certainly not recommending it. It will make your code hard to test, and I doubt it's officially supported so there's no guarantee the provider will work even if you can access it.
That said, if you need to do this and it works then so be it. Just be sure to test vigorously! :)
I've never used the ui.router module, but I believe it has to be setup in the config because the routes have to be setup before the app is initiated. From my understanding, it works basically the same as the $routeProvider, in that you have to setup everything you want to do in the config.
Its not explicitly said anywhere (that I can see), but the docs/examples found here seem to suggest that the $routeProvider can only be accessed from within a module declaration (ie app.module('myMod', [], function($routeProvider){ ... })) or inside of the app.config function.
I'm going to guess that the $stateProvider acts the same way.
Related
I only see .config with passing $routeProvider, what else will passing through by .config and also want to know what are the parameters will pass through by .run in angularjs
These are dependency injected services.
So for config you should be asking for constant or provider. For run you should be asking for service, factory, value, constant.
You should notice i'm saying should be asking for, because we're dependency injecting the services, the function parameters are effectively asking angular DI for particular instances. If angular has one it will supply the function arg with that instance, similar to a fn.call({}, someDep)
So for example:
angular.module('myMod', [])
.provider('myFactory', myFactoryProvider)
.factory('anotherService', anotherServiceFactory)
.config(function (myFactoryProvider) {
})
.run(function (myFactory, anotherService) {
/** myFactory is the service that was setup
* by the config myFactoryProvider
*/
});
I've left out the implementations for myFactoryProvider and anotherServiceFactory so you look up angular docs to see what they're about.
The config and run describe the phases of an angular application. config phase is for setting up services and pipelines like the $http request pipeline and generally pre-app configuration.
The run phase is for when the app has loaded and you want to do something like load some user information from the api or anything else post-app load.
I personally used to use the config all the time with $stateProvider and things. But, I rarely used the run function.
I was surprised to learn that ui-router shares state across modules.
That's ok, but for our development environment I'd like to clear all the application states and start from scratch.
It's not convenient to avoid defining them in the first case just for our test environment, because the state definition is mixed in with all the other application loading, and we'd like to be sure that the application dependencies are describe the same way in all environments.
So can I clear, or remove one-by-one, the already defined states?
.config( function($stateProvider) {
// TODO: get rid of $state definitions from the app, we don't want them here
}
With angular-ui-router starting from Version 1.0.0 (currently in rc1 version) it is now possible to properly remove states.
Inject $stateRegistry (runtime) or $stateRegistryProvider (config) and call the deregister() method.
Here the detailed API, implemented with this commit
This is not possible. ui-router uses ng-router and ng-router does not expose the routes until after the provider is compiled. Meaning you wouldn't be able to remove states/routes until the app is configured. Which I don't think they will accept a PR.
Edit:
In response to the comment made. The routes objects used by the $routerProvider is available and you can remove routes.
https://github.com/angular/angular.js/blob/master/src/ngRoute/route.js#L451
delete $route.routes['/'];
But the states object used by the $stateProvider is not available.
https://github.com/angular-ui/ui-router/blob/a7d25c6/src/state.js
So ui-router would need to be modified to be able to remove states after config. OR ng-router would need to be modified to be able to remove routes during config.
When loading a routing address into the routeProvider in .config stage, I want to sametime setup the route addresses under $rootScope, so that all the other services can access the routing correctly.
for example, like this:
$rootScope.jsModules='js/modules/';
$rootScope.appModule={
addressbookHomeModule: {
mName:'homeController',
route: 'addressbook-home/',
template: route+'home.html',
controller: route+'homeController.js',
},
However, I found and researched that its not possible to config $rootScope at the point of .config.
If its possible to config $rootScope just by attaching another object onto it, may I ask the way to do that, if possible an example will be a great help.
If no, I wonder if there a better way and more efficient way to store the routing location string like partials/confirmed.html so that all the other services can access the route correctly when I only need to config the string of the routing location once instead of all around the files in all the services?
We can use angular.constant..We can inject constants into pretty much anything (factory service provider etc) once its created.for eg
Angular.module('app).constant('routes',{home:'/'})
In the Sample Angular App
For example, in one obscure module of the app, there is a route like:
$routeProvider.when('/projectsinfo', {
templateUrl:'projectsinfo/list.tpl.html',
controller:'ProjectsInfoListCtrl',
resolve:{
projects:['Projects', function(Projects){
return Projects.all();
}]
}
});
I have two questions about this:
1) How does Angular locate this path and put it together with its registry of other paths? Is it because the same $routeProvider is used?
2) Is this a bad coding practice - i.e. putting routes in different modules? Are there advantages to doing it?
I would love if someone could enlighten me. I am just starting out with Angular.
Even though a provider (like routeProvider) can be used in multiple modules (and those modules are dependent on each other), the provider is instantiated only once, which makes is a singleton. So in every module you are dealing with the same provider. Since every module has its own config phase, you can configure it again and in this case the registration ends up in the same registry (internally).
So to answer your first question: yes, it is because the same $routeProvider is used.
To answer your second question: I am a little hesitant to say that this is good coding practice because I haven't seen this pattern anywhere else. But there is definitely potential in it, because you can create modules that are about a set of functionality including pages. It makes sense to define routes for that set of functionality inside that module, so all knowledge about it lives inside that module.
The downside is that urls can be overwritten in other modules that are loaded later on, especially by the main app that takes these modules as dependencies.
angular.module('app',['a','b']);
So if in module 'a' you have '/home' defined as route as well as in 'app', the one defined in 'app' will overwrite the one defined in 'a'.
I'm pretty new to AngularJS, so far I have learnt that providers are used to configure the services that will be used later during the execution phase. Particularly, routes are configured during the configuration phase using $routeProvider and then we can access the routes in our controller using the service $route.
I would like to know if once I have set up the routes with $routeProvider, if it's possible to modify the routes, add new ones or delete existing ones using the service $route (during the execution phase). So basically if we can have a kind of dynamic routes, and if so, how can we achieve this.
Thank you!!
nope, the $route service is configured during the config phase via the $routeProvider service, and this phase happens only once when starting the app.
If you want to add dynamic behavior to the url, you ca still manipulate the search parameter thanks to $location.search().
(and then $watch the changes or whatever you want to do)