Angular UI 路由器嵌套状态在子状态中解析 [英] Angular UI Router Nested State resolve in child states

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

问题描述

在我正在开发的 Angular 应用程序中,我希望有一个抽象的父状态,它必须解决其所有子状态的某些依赖关系.具体来说,我希望所有需要经过身份验证的用户从某个 authroot 状态继承该依赖项的状态.

我遇到了父依赖项并不总是被重新解决的问题.理想情况下,我想让父状态检查用户是否仍然自动登录任何子状态.在 文档,它说

<块引用>

子状态将从父状态继承解析的依赖项,它们可以覆盖.

我发现只有当我从父状态之外的状态进入任何子状态时才会重新解析父依赖关系,但如果在兄弟状态之间移动则不会.

在此示例中,如果您在状态 authroot.testA 和 authroot.testB 之间移动,则 GetUser 方法仅被调用一次.当您移动到 ​​other 状态并返回时,它将再次运行.

我可以将 User 依赖放在每个子状态上,以确保每次进入这些状态时都会调用该方法,但这似乎违背了继承依赖的目的.

我对文档的理解有误吗?有没有办法强制父状态重新解析它的依赖,即使状态在兄弟之间发生变化?

jsfiddle

<头><script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.0/angular-ui-router.min.js"></script><脚本>(功能(ng){var app = ng.module("Test", ["ui.router"]);app.config(["$stateProvider", "$urlRouterProvider", function(sp, urp) {urp.otherwise("/testA");sp.state("authroot", {摘要:真实,网址:"",模板: "

",解决:{用户:[用户服务",功能(用户服务){console.log("正在解决依赖...");返回 UserService.GetUser();}]}});sp.state("authroot.testA", {网址:/testA",模板:<h1>Test A {{User|json}}</h1>",控制器:TestCtrl"});sp.state("authroot.testB", {网址:/testB",模板:<h1>测试 B {{User|json}}</h1>",控制器:TestCtrl"});sp.state(其他",{网址:/其他",模板:<h1>其他</h1>",});}]);app.controller("TestCtrl", ["$scope", "User", function($scope, User) {$scope.User = User;}]);app.factory("UserService", ["$q", "$timeout", function($q, $timeout) {函数 GetUser() {console.log("正在从服务器获取用户信息...");var d = $q.defer();$超时(功能(){console.log("获取用户信息.");d.resolve({用户名:"JohnDoe1", OtherData: "asdf"});}, 500);返回 d. 承诺;};返回 {获取用户:获取用户};}]);})(window.angular);<body ng-app="测试"><a ui-sref="authroot.testA">转到A</a><a ui-sref="authroot.testB">转到B</a><a ui-sref="other">转到其他</a><div ui-view>正在加载...</div></html>

解决方案

我发现 ui-router 的特殊之处在于您刚刚描述的行为.

让我们考虑一些实体,例如接触.因此,如果右侧显示联系人列表,左侧显示详细信息,那就太好了.请查看基础知识使用 ui-router 和 AngularJS 快速了解布局.引用:

<块引用>

ui-router 完全包含路由系统的状态机特性.它允许您定义状态,并将您的应用程序转换为那些州.真正的胜利在于它允许您解耦嵌套状态,并以优雅的方式做一些非常复杂的布局.

您需要以不同的方式考虑您的路由,但是一旦您了解基于状态的方法,我想你会喜欢

好吧,为什么会这样?

因为我们可以有一个状态 Contact 代表一个列表.从细节的角度说一个固定的列表.(现在跳过列表分页过滤) 我们可以点击列表并移动到状态 Contact.Detail(ID),以查看刚刚选择的项目.然后选择另一个联系人/项目.

嵌套状态的优点来了:

<块引用>

列表(状态Contact)重新加载.而子状态 Contact.Detail 是.

这应该可以解释为什么怪异"行为应该被视为正确的.

回答您的问题,如何处理用户状态.我会使用路由状态的一些非常顶级的兄弟,其分离的视图和控制器以及一些生命周期周围......在某些循环中触发

In an angular app I'm working on, I'd like there to be an abstract parent state which must resolve certain dependencies for all of its children's states. Specifically, I'd like all states requiring an authenticated user to inherit that dependency from some authroot state.

I'm running into issues having the parent dependency not always being re-resolved. Ideally, I'd like to have the parent state check that the user is still logged in for any child state automatically. In the docs, it says

Child states will inherit resolved dependencies from parent state(s), which they can overwrite.

I'm finding that the parent dependency is only being re-resolved if I enter any child state from a state outside the parent, but not if moving between sibling states.

In this example, if you move between states authroot.testA and authroot.testB, the GetUser method is only called once. When you move to the other state and back, it will get run again.

I am able to put the User dependency on each of the child states to ensure the method is called every time you enter any of those states, but that seems to defeat the purpose of the inherited dependency.

Am I understanding the docs incorrectly? Is there a way to force the parent state to re-resolve its dependencies even when the state changes between siblings?

jsfiddle

<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.0/angular-ui-router.min.js"></script>
<script>
(function(ng) {
    var app = ng.module("Test", ["ui.router"]);
    app.config(["$stateProvider", "$urlRouterProvider", function(sp, urp) {
        urp.otherwise("/testA");
        sp.state("authroot", {
            abstract: true, 
            url: "",
            template: "<div ui-view></div>", 
            resolve: {User: ["UserService", function(UserService) {
                        console.log("Resolving dependency...");
                        return UserService.GetUser();
                    }]}
        });
        sp.state("authroot.testA", {
            url: "/testA", 
            template: "<h1>Test A {{User|json}}</h1>", 
            controller: "TestCtrl"
        });
        sp.state("authroot.testB", {
            url: "/testB", 
            template: "<h1>Test B {{User|json}}</h1>", 
            controller: "TestCtrl"
        });
        sp.state("other", {
            url: "/other", 
            template: "<h1>Other</h1>", 
        });
    }]);
    app.controller("TestCtrl", ["$scope", "User", function($scope, User) {$scope.User = User;}]);
    app.factory("UserService", ["$q", "$timeout", function($q, $timeout) {
        function GetUser() {
            console.log("Getting User information from server...");
            var d = $q.defer();
            $timeout(function(){
                console.log("Got User info.");
                d.resolve({UserName:"JohnDoe1", OtherData: "asdf"});
            }, 500);
            return d.promise;
        };
        return {
            GetUser: GetUser
        };
    }]);
})(window.angular);
</script>
</head>
<body ng-app="Test">
    <a ui-sref="authroot.testA">Goto A</a>
    <a ui-sref="authroot.testB">Goto B</a>
    <a ui-sref="other">Goto Other</a>
    <div ui-view>Loading...</div>
</body>
</html>

解决方案

The way I find the ui-router exceptional, is in the behaviour you've just described.

Let's think about some entity, e.g. Contact. So it would be nice to have a right side showing us the list of Contacts, the left part the detail. Please check the The basics of using ui-router with AngularJS for quick overvie about the layout. A cite:

ui-router fully embraces the state-machine nature of a routing system. It allows you to define states, and transition your application to those states. The real win is that it allows you to decouple nested states, and do some very complicated layouts in an elegant way.

You need to think about your routing a bit differently, but once you get your head around the state-based approach, I think you will like it.

Ok, why that all?

Because we can have a state Contact representing a List. Say a fixed list from perspective of the detail. (Skip list paging filtering now) We can click on the list and get moved to a state Contact.Detail(ID), to see just selected item. And then select another contact/item.

Here the advantage of nested states comes:

The List (the state Contact) is not reloaded. While the child state Contact.Detail is.

That should explain why the "weird" behaviour should be treated as correct.

To answer your question, how to handle user state. I would use some very top sibling of a route state, with its separated view and controller and some lifecycle arround... triggered in some cycles

这篇关于Angular UI 路由器嵌套状态在子状态中解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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