ANGULAR-UI-ROUTER:从 URL 解析状态 [英] ANGULAR-UI-ROUTER: Resolve state from URL

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

问题描述

我正在制作一个具有动态状态的应用程序,有时我需要从 url 解析状态名称.

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

例如:我有 /dashboard/user/12268 并且我需要获取状态 'dashboard.user'.

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

有没有办法用ui-router 提供的工具做到这一点?我现在不知道该怎么做...

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...

我正在使用 requireJS 制作一个带有动态模块加载的应用程序.第一次没有问题,因为用户被发送到登录状态.登录后,我使用 require 仅加载用户有权访问的状态.但是当用户重新加载页面时,我再次加载模块,并且需要将 url 解析为状态,这就是问题所在.我已经开始尝试使用 urlMatcherFactory 但无法解决它们.

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.

状态在 URL 解析后加载.

The state is loaded after the URL resolution.

流程是(页面刷新后http://localhost:8090/index.html#/dashboard/user/12268):

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

  • 引导应用程序(无状态)
  • 此时,ui-router已经加载
  • 获取用户有权访问的状态,并注册它们(这些状态在配置阶段之后注册)
  • 找出我是否有一个与给定 url 匹配的状态以重定向到那里.这就是我被困的地方.

为了在应用程序引导后加载状态,我使用了 Ben Nadel 的解决方案,包括状态和常量.

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

我在RequireJS中的data-main有这样的初始化代码:

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

loadManifest 函数在我的应用程序(服务、工厂、控制器、路由器等)上注册所有引导后元素.

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

您可以通过使用 $stateProvider 上的 .decorator 钩子来公开内部状态实现.您可以装饰状态生成器的任何属性;我随意选择了父母".

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

<小时>

现在您可以使用 .$$state() 访问内部状态对象,例如


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

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

<小时>

其次,遍历 $state.get() 中的每个状态,并针对您的 URL 片段进行测试.


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

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

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