' UI-Router-Extras'-不能附加/添加新的&FutureState'App.Config()已加载后的对象 [英] 'UI-Router-Extras' - Can't Attach / Add New 'FutureState' Objects After App.Config() Has Already Loaded

查看:50
本文介绍了' UI-Router-Extras'-不能附加/添加新的&FutureState'App.Config()已加载后的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用" UI-Router-Extras "向我的应用的运行时阶段添加新状态时遇到问题.

I am having problems with adding new states to the runtime phase of my app using 'UI-Router-Extras'.

我已经尝试了很长一段时间,以便在用户使用" UI-Router-Extras "插件成功通过身份验证之后,便可以附加并加载新的状态:

I have been trying for quite some time now to get new states attached and loaded AFTER a user has successfully authenticated using the 'UI-Router-Extras' plugin 'ui-router-extras'

此处引用了"UI-Router-Extras"示例用于我正在使用的FutureState文档,但是我觉得我的情况可能与显示的内容略有不同,或者我完全丢失了某些内容.

Here is a reference to the 'UI-Router-Extras' Examples for the FutureState documentation that i'm using, but I feel like maybe my scenario is either slightly different that what's shown or I'm missing something altogether.

插入器中的示例代码-单击登录按钮-> http://plnkr.co/edit/PQwNQcLNMyPfpke076yy

EXAMPLE CODE IN PLUNKER - CLICK LOGIN BUTTON -> http://plnkr.co/edit/PQwNQcLNMyPfpke076yy


下面的代码可以正常工作


我成功地从外部文件中延迟加载了初始app.config().像下面描述的代码一样:


I was successful in getting the initial app.config() lazy loaded from an external file. Like the code describes below:


公共-使用"UI-Router-Extras"的外部初始加载路由-"lazyload/states/public-states.json"

[
    {
        "name": "unauth",
        "url": "/",
        "controller": "LoginCtrl",
        "templateUrl": "app/components/core/login/login.html",
        "roles": ["public"]
    },
    {
        "name": "otherwise",
        "url": "/",
        "roles": ["public"]
    }
]

初始应用加载-成功的公共状态的延迟加载从登录开始:

'use strict';

var app = angular.module('app', ['ui.router', 'ct.ui.router.extras'])

  .config(function ($urlRouterProvider, $stateProvider, $futureStateProvider) {

        app.stateProvider = $stateProvider; // MIGHT NEED REFERNCE LATER?
        app.futurestateProvider = $futureStateProvider;  // MIGHT NEED REFERNCE LATER?

        // ASYNC LOAD OF ROUTES AVAILABLE - SOON TO BE BY ROLE
        var futureStateResolve = ["$http", function($http) {
            return $http.get("lazyload/states/public-states.json").then(function(response) {
                angular.forEach(response.data, function(state) {

                    $stateProvider.state(state);
                    console.log(state.roles);

                })
            })
        }];

        $futureStateProvider.addResolve(futureStateResolve);
        console.log($futureStateProvider);

  });



下面的代码不起作用


以下是我对无效部分的代码:

PRIVATE-使用'UI-Router-Extras'-'lazyload/states/public-states.json'的外部初始加载路由

下面的json用于在用户使用延迟加载和FutureStates登录后添加.到目前为止还没有运气:(

This json below is meant to be added after user login using lazy loading and FutureStates. So far no luck :(

[
    {
        "name": "app",
        "abstract": true,
        "url": "?menu1State",
        "templateUrl": "app/components/core/layout/layout.html",
        "controller": "LayoutCtrl",
        "roles": ["level1"]
    },
    {
        "name": "app.dashboard",
        "url": "/app",
        "views": {
            "feature": {
                "templateUrl": "app/components/core/features/features.html",
                "controller": "FeatureCtrl"
            }
        },
        "roles": ["level1"]
    },
    {
        "name": "app.associations_beanbags",
        "url": "/app/associations/bean-bags?myParam1&myParam2&modalState",
        "views": {
            "feature": {
                "templateUrl": "app/components/core/features/associations/bean-bags.html",
                "controller": "BeanbagsCtrl"
            }
        },
        "roles": ["level2"]
    }
]

成功通过身份验证后,登录按钮将触发状态的延迟创建:

Login button triggering the lazy creation of states after successful authentication:

<a id="btn-fblogin" href="" class="btn btn-primary pull-right" ng-click="callNotify(username, password);">Login</a>


发生的情况是,当用户单击登录按钮时,它会模拟成功并调用"$ scope.callNotify ",从而触发您在下面看到的代码.最终发生的事情是一切正常,直到' app.futurestateProvider.futureState(newState); ',并尝试调用新状态以查看是否添加了' $ state.go('app.dashboard'); '.所有这些都会导致显示以下错误:

What happens is when a user clicks on a login button it mocks the success and calls '$scope.callNotify' triggering the code you see below. What ends up happening is everything works up until the 'app.futurestateProvider.futureState(newState);' and the trying to call the new state to see if was added '$state.go('app.dashboard');'. All of this results in an error that states the following:

控制台错误:

Error: Could not resolve 'app.dashboard' from state 'unauth'
at Object.transitionTo (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:2521:17)
at Object.$state.transitionTo (http://localhost:3000/bower_components/ui-router-extras/release/ct-ui-router-extras.js:136:34)
at Object.$state.transitionTo (http://localhost:3000/bower_components/ui-router-extras/release/ct-ui-router-extras.js:874:55)
at Object.$state.transitionTo (http://localhost:3000/bower_components/ui-router-extras/release/ct-ui-router-extras.js:1301:48)
at Object.go (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:2454:21)
at http://localhost:3000/app/components/core/auth/auth-service.js:58:13
at http://localhost:3000/bower_components/angular/angular.js:8113:11
at wrappedCallback (http://localhost:3000/bower_components/angular/angular.js:11573:81)
at wrappedCallback (http://localhost:3000/bower_components/angular/angular.js:11573:81)
at http://localhost:3000/bower_components/angular/angular.js:11659:26 

所以对我来说,这是我们从未真正添加过我们所期望的州,从而导致出现类似抱歉,我没有找到您要寻找的路线"之类的信息.

So what this looks like to me is that the states never really got added when we expected, thus causing an error saying something to the likes of "Sorry, i don't see the route you are looking for."

'use strict';

app.controller('AuthServiceTestCtrl', ['$window','$scope','$http', '$state', function (win, $scope, $http, $state) {

    $scope.callNotify = function(username,password, $stateProvider, $futureStateProvider) {
            //notify(username, password); // CALL SERVICE AND GET A RETURN VALUE / ACTION

            var loadedAgain = $http.get("lazyload/states/private-states.json").success(function(response) {

                if(username == "testuser@example.com" && password == "abc123"){

                    console.log('Valid Credentials. Logging In.');

                    // NOW THAT USER IS LOGGED IN REGISTER NEW PRIVATE ROUTE / STATES - PREFERABLY FROM THE SECURED SERVER FILE ('private-states.json') ABOVE
                    var adminModuleFutureStates = [
                        {
                            "name": "app",
                            "abstract": true,
                            "url": "?menu1State",
                            "templateUrl": "app/components/core/layout/layout.html",
                            "controller": "LayoutCtrl",
                            "roles": ["level1"]
                        },
                        {
                            "name": "app.dashboard",
                            "url": "/app",
                            "views": {
                                "feature": {
                                    "templateUrl": "app/components/core/features/features.html",
                                    "controller": "FeatureCtrl"
                                }
                            },
                            "roles": ["level1"]
                        },
                        {
                            "name": "app.associations_bean-bags",
                            "url": "/app/associations/bean-bags?myParam1&myParam2&modalState",
                            "views": {
                                "feature": {
                                    "templateUrl": "app/components/core/features/associations/bean-bags.html",
                                    "controller": "BeanBagsCtrl"
                                }
                            },
                            "roles": ["level2"]
                        }
                    ];

                    angular.forEach(adminModuleFutureStates, function(newState) {
                        console.log(newState);
                        app.futurestateProvider.futureState(newState); // WAS SAVED AS A VAR IN APP CONFIG FOR LATER REFERENCE
                    });

                    // FINALLY GO TO ONE OF THE NEWLY ADDED PRIVATE STATES WE JUST ADDED WHICH IS A DASHBOARD
                    $state.go('app.dashboard');

                }
            });

        };
    }]);

对于尚未准备好可行的示例,我感到非常抱歉,我现在正在讨论,但我想现在就发布此内容,以展示我的经验,并可能就我的方式进行讨论或解决.在应用程序已经加载了配置等之后,可以通过上面列出的我的控制器在运行时将状态加载到ui-router.

I'm very sorry for not having a working example ready, I'm on it right now, but i figured i'd post this now to show what I do have and possibly get a discussion or solution as to how I can load states to ui-router at runtime via my controller listed above after the application has already loaded the config etc..

我最终要在这里做的是:

What I'm trying to ultimately do here is this:

我真的只需要公开两个安全的公共路线即可开始登录.然后,一旦用户登录了以前的公用路由,我就会尝试用新路由添加或装饰现有路由,现在这些新路由仅允许用户访问其角色提供的路由.对我们来说,安全性非常重要,并且我看不到任何好处,无论是在登录页面上预先加载每条可能的路由,让某人至少不用登录即可知道api或服务器溃败的原因.

I really need to only expose two safe public routes to begin with on login. Then once a user logs in the previous public routes stay and i'm trying to add or decorate the existing routes with new ones that now allow the user to only have access to the routes their role provides. Security for us is extremely important and I do not see any benefit whatsoever loading every possible route upfront on a login page letting someone know what out api or server routs are without at least being logged in.

非常抱歉,但我得出的结论是,我只是平平无奇地做错了事,需要一些额外的眼睛来了解为什么我不能在加载后添加新状态.

I'm very sorry for rambling but I've come to the conclusion that I'm just flat doing it wrong and need some extra eyes to maybe catch why i can't add new states post load.

非常感谢您!

插入器中的示例代码-单击登录按钮-> http://plnkr.co/edit/PQwNQcLNMyPfpke076yy

EXAMPLE CODE IN PLUNKER - CLICK LOGIN BUTTON -> http://plnkr.co/edit/PQwNQcLNMyPfpke076yy

推荐答案

我决定改用$ ocLazyLoad服务,但仍使用应用程序注入器在应用程序加载并使用基本配置进行初始配置后动态添加路由认证前的公共路线等.

angular.module("app").configInjector.invoke(['$stateProvider', function ($stateProvider) {

然后在设置应用注入器并验证用户身份并通过服务器验证了角色之后,定义允许的ui路由器视图/路由/状态的json响应将循环并动态添加到ui-路由器状态定义.这些路由在json中定义,但是使用$ ocLazyLoad延迟加载的所有随附控制器和视图也是如此.

Then after the app injector was setup and the user was authenticated and a role(s) was validated by the server a json response defining the allowed ui-router views / routes / states are looped over and added dynamically to the ui-router state definitions. These routes are defined in the json but so is any accompanying controllers and views that are lazy loaded using $ocLazyLoad.

我最终要做的所有事情如下:

angular.module("auth")
.factory('AuthRouteLoaderFactory', ['$window', '$rootScope', '$http', '$state', '$cookieStore','$location', '$timeout','AuthSession',
    function(win, $rootScope, $http, $state, $cookieStore, $location, $timeout, AuthSession) {

        // PRIVATE INTERFACE
        function loadPrivateRoutes() {

            console.log('AuthRouteLoaderFactory :: LOADING PRIVATE ROUTES');

            var loadedPrivateRoutes = $http.get("lazyload/states/private-states.json").success(function (response) {

        angular.module("app").configInjector.invoke(['$stateProvider', function ($stateProvider) {

                    // VERY IMPORTANT - POST LOGIN ROUTE LOADER / INJECTOR;// DYNAMIC AND SERVER DETERMINED JSON ITERATED BASED ON SPECIFIC ROLES PRE-MADE BY SERVER.
                    angular.forEach(response, function (state) {

                        if(!state.abstract){
                            state.views.feature.resolve[state.views.feature.data.controllerAlias] = ['$ocLazyLoad', function($ocLazyLoad){return $ocLazyLoad.load({"name": state.views.feature.data.controllerAlias,"files": state.views.feature.data.controllerFiles})}];
                            state.views.feature.resolve.isAuthenticated = function(){
                // CHECK IF WE ARE A VALID SESSION FOR EACH LAZY LOAD
                //AuthSession.validateToken();
              };
                        }

                        console.log('AuthRouteLoaderFactory :: loadPrivateroutes state loaded -> ' + state.name);
                        $stateProvider.state(state.name, state);
                    });

                    $state.go('app.dashboard');

                }]);

            });

        }

        // FOR NOW WE LOAD ROUTES ANYWAY UNTIL WE CALL API'S /ME OR PING SERVICE, THEN ON SUCCESS WE LOAD ROUTES
        if(AuthSession.validateToken()){
          $rootScope.hideLoader = true;
          loadPrivateRoutes();
          console.log('AuthRouteLoaderFactory :: SESSION VALIDATION SUCCESSFUL :: PROCEED');
        }

        // PUBLIC INTERFACE
        return {
            testFactory: function() {
                console.log('AuthRouteLoaderFactory :: testFactory');
            },
            isSessionValid: function(){
                return $cookieStore.get('fakeLoginSession');
            },
            invalidateSession: function(){
                $cookieStore.remove('fakeLoginSession');
                $location.path('/login.html');
            },
            loadRoutes: loadPrivateRoutes
        };
    }
]);

公共州/路线:

[
    {
        "name": "unauth",
        "url": "/",
        "controller": "LoginCtrl",
        "templateUrl": "app/components/core/login/unauth.html",
        "data": {
            "roles": ["public"]
        }
    },
    {
        "name": "login",
        "url": "/login",
        "controller": "LoginCtrl",
        "templateUrl": "app/components/core/login/unauth.html",
        "data": {
            "roles": ["public"]
        }
    },
    {
        "name": "otherwise",
        "url": "/",
        "data": {
            "roles": ["public"]
        }
    }
]

私人州/路线:

[
    { "name": "app", "abstract": true, "url": "", "templateUrl": "app/components/core/layout/layout.html", "controller": "LayoutCtrl" },
    {
        "name": "app.dashboard",
        "views": {
            "feature": {
                "templateUrl": "lazyload/components/core/features/dashboard/dashboard.html",
                "controller": "DashboardCtrl as dashboard",
                "resolve": {},
                "data": {
                    "controllerAlias": "dashboard",
                    "controllerFiles": ["lazyload/components/core/features/dashboard/dashboard-controller.js"]
                }
            }
        }
    },
    {
        "name": "app.associations_role-type",
        "views": {
            "feature": {
                "templateUrl": "lazyload/components/core/features/associations/role-type.html",
                "controller": "RoleTypeCtrl as roleType",
                "resolve": {},
                "data": {
                    "controllerAlias": "roleType",
                    "controllerFiles": ["lazyload/components/core/features/associations/role-type-controller.js"]
                }
            }
        }
    }
]

这篇关于&amp;#39; UI-Router-Extras&amp;#39;-不能附加/添加新的&FutureState&amp;#39;App.Config()已加载后的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆