角UI路由器:解决从URL状态 [英] ANGULAR-UI-ROUTER: Resolve state from URL

查看:148
本文介绍了角UI路由器:解决从URL状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与动力状态的应用程序,有时我需要从URL解析国家名称。

例如:我有 /仪表板/用户/ 12268 ,我需要得到国家'dashboard.user

有什么办法由给出的工具UI路由器来做到这一点?我无法找出如何做这方面的权利...

我在做动态加载模块与requireJS的应用程序。在第一时间,因为用户被发送到登录状态是没有问题的。登录后,我用只需要加载的用户可以访问的状态。但是,当用户重新加载页面,我再次加载模块,并且需要将URL解析到一个状态,还有就是问题所在。我已经开始与urlMatcherFactory努力,但解决不了他们。

的状态的URL解析后装入。

该流程(页面刷新后的http://本地主机:8090 / index.html的#/仪表板/用户/ 12268


  • 引导应用程序(不包括美国)

  • 在这一点上,<​​code> UI路由器已加载

  • 获取用户有权访问该国,并注​​册它们(这些国家被注册的配置相)

  • 找到了,如果我有一个给定的URL重定向到有相匹配的状态。这就是我卡住了。

要加载的应用程序后,引导状态,我用的<一个变化href=\"http://www.bennadel.com/blog/2554-loading-angularjs-components-with-requirejs-after-application-bootstrap.htm\"相对=nofollow>本纳德尔的解决方案,包括国家和常量。

我的数据主在RequireJS有这个初始化code:

\r
\r

require.config({\r
    // REQUIREJS配置\r
});\r
\r
需要(['应用'],功能(应用程序){\r
    app.bootstrap(文件);\r
\r
    VAR纳克= angular.injector(['NG']);\r
    变量$ =窗口ng.get('$窗口)\r
    变量$ Q = ng.get('$ Q');\r
\r
    VAR appStorage = $ window.localStorage;\r
    VAR loadedManifests;\r
\r
    尝试{\r
        loadedManifests = JSON.parse(appStorage.getItem('loadedManifests'));\r
    }赶上(E){\r
        loadedManifests = [];\r
    }\r
\r
    如果(!angular.isArray(loadedManifests)|| loadedManifests.length === 0){\r
        $ q.all([\r
                app.loadManifest(登录/清单),// loadMainfest函数加载状态进行登录\r
                app.loadManifest('注销/清单)//负载注销状态\r
            ])\r
            。然后(函数(){\r
                app.injector.get('$ rootScope')。$ evalAsync(函数(){\r
                    。app.injector.get('$状态')去('密码');\r
                });\r
            });\r
    }其他{\r
        变种promisesArray = [];\r
\r
        对于(VAR I = 0; loadedManifests [I];我++){\r
            promisesArray.push(app.loadManifest(loadedManifests [I])); //加载在localStorage的所有已注册的体现\r
        }\r
\r
        $ q.all(promisesArray)。然后(函数(){\r
            // TODO:卡住。从查询字符串获取URL和解决有效状态,或重定向到/登录\r
        });\r
    }\r
});

\r

\r
\r

loadManifest 功能寄存器毕竟,引导我的应用程序内容(服务,工厂,控制器,路由器,...)。

感谢您的帮助,

ALX


解决方案

的https: //github.com/angular-ui/ui-router/issues/1651

您可以使用 .decorator 勾上 $ stateProvider 暴露出内部状态的实现。您可以装点国家建设者的任何财产;我选择了父随意。


 的app.config(函数($ stateProvider){
  $ stateProvider.decorator(父,功能(internalStateObj,parentFn){
     //这个FN由StateBuilder每一个国家被注册时被调用     //第一个arg是内部状态。捕捉它,并添加一个访问公共状态的对象。
     。internalStateObj.self $$状态=函数(){返回internalStateObj; };     //通过默认.parent()函数
     返回parentFn(internalStateObj);
  });
});


现在您可以通过访问内部状态对象。$$状态(),例如

  VAR publicState = $ state.get(富);
VAR privateInternalState = publicState $$状态()。


二,循环遍历$ state.get(每个州),并测试他们对你的URL片段。

  angular.forEach($ state.get()函数(州){
  VAR privatePortion =状态$$状态()。
  VAR匹配= privatePortion.url.exec(URL,queryParams);
  如果(匹配)的console.log(匹配的状态:+ state.name +和参数:+匹配);
});

I'm making an app with dynamical states, and sometimes I need to resolve the state name from the url.

e.g.: I have /dashboard/user/12268 and I need to get the state 'dashboard.user'.

Is there any way to do this with the tools given by ui-router? I can't find out how to do this right now...

I'm making an app with dynamic module loading with requireJS. At first time there is no problem because user is sent to login state. After login, I use require to load only the states the user has access to. But when the user reloads the page, I load the modules again, and need to resolve the url to a state, and there's the problem. I've started trying with urlMatcherFactory but can't resolve them.

The state is loaded after the URL resolution.

The flow is (after the refresh of page http://localhost:8090/index.html#/dashboard/user/12268):

  • bootstrap the app (without states)
  • at this point, ui-router has been loaded
  • get the states the user has access to, and register them (these states are registered after config phase)
  • find out if i have a state that matches the given url to redirect to there. This is where I'm stuck.

To load states after application bootstrap, I've used a variation of Ben Nadel's solution that includes states and constants.

My data-main in RequireJS has this initialization code:

require.config({
    // REQUIREJS CONFIGURATION
});

require(['app'], function (app) {
    app.bootstrap(document);

    var ng = angular.injector(['ng']);
    var $window = ng.get('$window')
    var $q = ng.get('$q');

    var appStorage = $window.localStorage;
    var loadedManifests;

    try {
        loadedManifests = JSON.parse(appStorage.getItem('loadedManifests'));
    } catch(e) {
        loadedManifests = [];
    }

    if (!angular.isArray(loadedManifests) || loadedManifests.length === 0) {
        $q.all([
                app.loadManifest('login/manifest'), //loadMainfest function loads the states for login
                app.loadManifest('logout/manifest') //load states for logout
            ])
            .then(function () {
                app.injector.get('$rootScope').$evalAsync(function () {
                    app.injector.get('$state').go('login');
                });
            });
    } else {
        var promisesArray = [];

        for(var i = 0; loadedManifests[i]; i++) {
            promisesArray.push(app.loadManifest(loadedManifests[i])); //load all manifests registered on localstorage
        }

        $q.all(promisesArray).then(function(){
            //TODO: Stuck. Get URL from querystring and resolve to valid state, or redirect to /login
        });
    }
});

TheloadManifest function registers all after-bootstrap elements on my app (services, factories, controllers, routers, ...).

Thanks for your help,
Alx

解决方案

https://github.com/angular-ui/ui-router/issues/1651

You can expose the internal state implementation by using the .decorator hook on $stateProvider. You can decorate any property of the state builder; I chose 'parent' arbitrarily.


app.config(function($stateProvider) { 
  $stateProvider.decorator('parent', function (internalStateObj, parentFn) {
     // This fn is called by StateBuilder each time a state is registered

     // The first arg is the internal state. Capture it and add an accessor to public state object.
     internalStateObj.self.$$state = function() { return internalStateObj; };

     // pass through to default .parent() function
     return parentFn(internalStateObj); 
  });
});


Now you can access the internal state object using .$$state(), e.g.

var publicState = $state.get("foo");
var privateInternalState = publicState.$$state();


Second, loop over each state in $state.get() and test them against your URL fragment.

angular.forEach($state.get(), function(state) { 
  var privatePortion = state.$$state();
  var match = privatePortion.url.exec(url, queryParams);
  if (match) console.log("Matched state: " + state.name + " and parameters: " + match);
});

这篇关于角UI路由器:解决从URL状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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