【问题标题】:Angular UI Router Nested State resolve in child statesAngular UI Router 嵌套状态在子状态中解析
【发布时间】:2013-12-13 00:38:04
【问题描述】:

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

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

子状态将从父状态继承已解决的依赖关系,它们可以覆盖这些依赖关系。

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

在这个例子中,如果你在 authroot.testA 和 authroot.testB 状态之间移动,GetUser 方法只会被调用一次。当您移动到other 状态并返回时,它将再次运行。

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

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

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>

【问题讨论】:

    标签: angularjs angular-ui-router


    【解决方案1】:

    我发现 ui-router 异常的方式在于您刚才描述的行为。

    让我们考虑一些实体,例如接触。所以最好有一个右侧向我们显示联系人列表,左侧部分显示详细信息。请查看The basics of using ui-router with AngularJS 以快速了解布局。引用:

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

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

    好吧,为什么会这样?

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

    嵌套状态的优势就在这里:

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

    这应该可以解释为什么“奇怪”的行为应该被视为正确的。

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

    【讨论】:

      【解决方案2】:

      真正的简短回答是使用:

      $rootScope.$on("$stateChangeStart")

      监听任何范围变化并采取适当的行动。

      更长的答案是,看看小提琴: http://jsfiddle.net/jasallen/SZGjN/1/

      请注意,我使用了 app.run,这意味着我正在为用户解析每个 状态更改。如果你想限制它在 authRoot 是 parentage 时的状态更改,请将 $stateChangeStart 的检查放在 authRoot 控制器中。

      【讨论】:

      • 我最终在您和 Radim 的建议之间做了一些混合 - 让状态解决自己的依赖关系,以及在用户服务对象上注册侦听器的层次结构之外的状态
      • @David 我们可以看到你最终做了什么吗?我遇到了类似的事情
      • @SonicTheLichen 当然,我今天会放一个小提琴给你看
      • 新示例:jsfiddle.net/2ebZj/1 现在,我可以使用 ResolveProvider.User 要求每个状态检查用户是否已登录。我的 ResolveProvider 中还有一些其他常用的解决方案
      • @SonicTheLichen 意识到我没有@你所以这里是这个评论以防万一
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 2015-07-05
      • 2015-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多