有没有办法在模块配置后以编程方式将状态添加到$ stateProvider,例如服务?
要为这个问题添加更多上下文,我有一种情况可以采用两种方法:
州定义
.state('index.resource.view', {
url: "/:resourceName/view?pageNumber&pageSize&orderBy&search",
templateUrl: "/resourceAdministration/views/view.html",
controller: "resourceViewCtrl",
reloadOnSearch: false,
})
答案 0 :(得分:109)
通常在配置阶段将状态添加到$stateProvider
。如果要在运行时添加状态,则需要保留对$stateProvider
周围的引用。
此代码未经测试,但应该执行您想要的操作。它创建了一个名为runtimeStates
的服务。您可以将其注入运行时代码,然后添加状态。
// config-time dependencies can be injected here at .provider() declaration
myapp.provider('runtimeStates', function runtimeStates($stateProvider) {
// runtime dependencies for the service can be injected here, at the provider.$get() function.
this.$get = function($q, $timeout, $state) { // for example
return {
addState: function(name, state) {
$stateProvider.state(name, state);
}
}
}
});
我已在UI-Router Extras中实施了一些名为未来状态的内容,这些内容可以帮助您处理一些极端情况,例如将网址映射到不存在的状态然而。 Future States还展示了如何延迟加载运行时状态的源代码。看看source code,了解所涉及的内容。
在UI-Router 1.0中,可以使用StateRegistry.register
和StateRegistry.deregister
在运行时注册和取消注册状态。
要访问StateRegistry,请将其注入$stateRegistry
,或注入$uiRouter
并通过UIRouter.stateRegistry
访问它。
UI-Router 1.0还包括开箱即用的Future States,用于处理状态定义的延迟加载,甚至可以通过URL进行同步。
答案 1 :(得分:14)
Chris T钉了它!提供者是要走的路。您不必将其打到窗口对象上,保护程序,更受保护等等。
通过本文交叉引用他的回答确实有帮助:http://blog.xebia.com/2013/09/01/differences-between-providers-in-angularjs/#provider
该解决方案在配置块期间使特定模块$ stateProvider在其运行块期间可供其他模块访问。
在我的情况下,我根据用户的权限动态生成仪表板状态。
在我的配置块中,我的提供程序已设置,传递模块的stateProvider(稍后将被访问)。
//in dashboard.module.js
var dashboardModule = angular.module('app.modules.dashboard',[
'app.modules.dashboard.controllers',
'app.modules.dashboard.services',
'app.modules.dashboard.presentations.mileage'
])
.provider('$dashboardState', function($stateProvider){
this.$get = function(PATHS, $state){
return {
addState: function(title, controllerAs, templatePrefix) {
$stateProvider.state('dashboard.' + title, {
url: '/' + title,
views: {
'dashboardModule@dashboard': {
templateUrl: PATHS.DASHBOARD + (templatePrefix ? templatePrefix + '/' : '/') + title + '/' + title + '.view.html',
controller: controllerAs ? controllerAs : null
}
}
});
}
}
}
});
这将使我的Dashboard状态提供程序可用于其他模块,而不是将其打到窗口上。
然后在我的用户模块的运行块(控制器)中,我可以访问仪表板的状态提供程序并动态注入状态。
var UserControllers = angular.module('app.modules.user.controllers', [])
.controller("UserLoginController", ["$state", "$dashboardState", function($state, $dashboardState){
$dashboardState.addState('faq', null, 'content');
$state.go('dashboard.faq');
}]);
答案 2 :(得分:4)
是的,可以这样做,但因为涉及缓存层,所以很复杂。 Alex Feinberg在他的博客上记录了一个解决方案:
本文的尾端包含一个使用stateProvider创建状态的示例:
app.stateProvider.state(ent.lob.name.toLowerCase(), {
url: '/' + ent.lob.name.toLowerCase(),
controller: ent.lob.name.toLowerCase() + 'Controller',
templateUrl: 'lobs/views/' + ent.lob.name.toLowerCase() + '.html'
});