【问题标题】:AngularJS - UI Router - programmatically add statesAngularJS - UI 路由器 - 以编程方式添加状态
【发布时间】:2014-11-10 01:29:42
【问题描述】:

有没有办法在模块配置后以编程方式向 $stateProvider 添加状态,例如服务 ?

要为这个问题添加更多上下文,我有一种情况可以采用两种方法:

  1. 尝试对模块配置中定义的状态强制重新加载,问题是状态有一个 reloadOnSearch 设置为 false,所以当我尝试 $state.go('state.name', {new:param}, {reload:true}); 什么都没发生,有什么想法吗?

状态定义

.state('index.resource.view', {
  url: "/:resourceName/view?pageNumber&pageSize&orderBy&search",
  templateUrl: "/resourceAdministration/views/view.html",
  controller: "resourceViewCtrl",
  reloadOnSearch: false,
})
  1. 尝试以编程方式添加我需要从服务加载的状态,以便路由能够正常工作。如果可能,我宁愿选择第一个选项。

【问题讨论】:

    标签: javascript angularjs angular-ui-router angular-services


    【解决方案1】:

    查看 -edit- 了解更新信息

    通常在配置阶段将状态添加到$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 的东西,可以为您处理一些极端情况,例如将网址映射到尚不存在的状态。 Future States 还展示了如何延迟加载运行时状态的源代码。查看source code 了解其中的内容。

    -edit- 用于 UI-Router 1.0+

    在 UI-Router 1.0 中,可以在运行时使用 StateRegistry.registerStateRegistry.deregister 注册和注销状态。

    要访问 StateRegistry,请将其注入为 $stateRegistry,或注入 $uiRouter 并通过 UIRouter.stateRegistry 访问它。

    UI-Router 1.0 还包括开箱即用的未来状态,它处理状态定义的延迟加载,甚至通过 URL 同步。

    【讨论】:

    • 感谢未来国家的贡献,克里斯!由于它的价值,我对此进行了投票,但将我的另一个答案留在下面,因为该博客文章也有一些有趣的花絮。
    • @ChadRobinson 也为你 +1
    • 我测试了这个解决方案,效果很好,我确实遇到了小问题,因为我使用了 'index.resource.DYNAMIC-STATE-NAME.view' 并且它是动态排队的状态可能是因为它被识别为父状态,只要我将状态名称更改为 'index.resource.DYNAMIC-STATE-NAMEView' 它就可以正常工作。
    • @ChrisT 现在我对延迟加载状态的直接 url 访问有问题,有没有办法在 404 重定向之前使用 $stateNotFound 或其他事件从服务加载状态?
    • @ChrisT 是否可以通过编程方式删除状态?
    【解决方案2】:

    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
                                }
                            }
                        });
                    }
                }
            }
        });

    这将使我的仪表板状态提供程序可用于其他模块,而不是在窗口上拍打。

    然后在我的用户模块的运行块(控制器)中,我可以访问仪表板的状态提供程序并动态注入状态。

    var UserControllers = angular.module('app.modules.user.controllers', [])
    
    .controller("UserLoginController", ["$state", "$dashboardState", function($state, $dashboardState){
    
        $dashboardState.addState('faq', null, 'content');
    
        $state.go('dashboard.faq');
    
    }]);

    【讨论】:

    • 到目前为止最简单的方法,不需要 AMD(如 Ui-Router Extras)。只需确保将提供程序添加到新模块中,否则将无法正常工作。
    • 您好,我尝试实现此功能,但出现错误提示未知提供者。如何在配置中注册提供程序。我想将提供程序注入控制器。
    • 我试过这个方法,但刷新时它不起作用。这不仅仅是时间问题。我收到大量的摘要错误
    【解决方案3】:

    是的,可以这样做,但是因为涉及到缓存层,所以它很复杂。 Alex Feinberg 在他的博客上记录了一个解决方案:

    http://alexfeinberg.wordpress.com/2014/03/08/dynamically-populating-angular-ui-router-states-from-a-service/

    文末包含一个使用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'
    });
    

    【讨论】:

    • 文章中的要点很少,但对我来说,用 stateProvider 扩展应用程序对象有点奇怪。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-12
    相关资源
    最近更新 更多