角文摘周期是运行,但NG绑定值不更新 [英] Angular Digest cycle being ran but ng-bind value not updating

查看:161
本文介绍了角文摘周期是运行,但NG绑定值不更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含导航栏父视图,该视图里面我有一个<格UI的视图> 这使得无论孩子认为我是元素上。

I have a parent view that contains a navbar, and inside of that view I have a <div ui-view> element which renders whatever child view I'm on.

我要有条件地显示/隐藏父视图中的导航栏,基于子视图的路线。现在,我有这样的:

I want to conditionally show/hide the navbar within the parent view, based on the route of the child view. Right now, I have this:

<nav ng-show="!vm.hideNavbar">

我的应用程序加载的第一次, vm.hideNavbar 设置为true,这按预期工作。

The first time my app is loaded, vm.hideNavbar is set to true and this works as expected.

vm.hideNavbar 更改为false,绑定的值不会被更新。它仍然是真正

After vm.hideNavbar is changed to false, the bound value is not updated. It is still true.

在我的应用程序的每个控制器扩展了这个 BaseController

Every controller in my app extends this BaseController:

export class BaseController {
        public hideNavbar: boolean;

        constructor(public $scope: IBaseScope, private $state: ng.ui.IStateService) {
            if ($state.current.url === '/login') {
                this.hideNavbar = true;
            } else {
                this.hideNavbar = false;
            }
            $scope.vm = this;
        }
 }

所以,每次新的控制器被加载,它要求 BaseController 构造函数和有条件地设置 $ scope.vm.hideNavbar 。如果我立即运行 $范围。$适用()在此构造年底,角抛出错误说摘要周期已经被跑。

So, everytime a new controller is loaded, it calls the constructor for BaseController and conditionally sets $scope.vm.hideNavbar. If I immediately run $scope.$apply() at the end of this constructor, angular throws errors saying the digest cycle is already being ran.

因此​​,消化周期正在跑,但在我看来价值不被更新。我唯一​​的想法是因为我最初的控制器和I导航既延长该控制器的控制,我实例化 BaseController 的多个副本。所以,现在,我的 vm.hideNavbar 还是看着老控制器限值。

So, the digest cycle is being ran, but the value in my view is not being updated. My only thought is that I have instantiated more than one copy of the BaseController since my initial controller and the controller I navigated to both extend this controller. So, now, my bound value of vm.hideNavbar is still looking at the old controller.

我在正确的轨道上这个吗?我怎样才能解决这个问题呢?

Am I on the right track with this? How can I solve this issue?

推荐答案

在这种情况下,我会建议去与 视图继承 (不是控制器,而不是状态的。在这里查看更多详细信息:

In this case, I would suggest to go with view inheritance (not controller, not state). Check more details here:

  • How do I share $scope data between states in angularjs ui-router?
  • How to inherit resolve data in ui-router

我们需要一个'根'状态。这将是在超级父其他任何的状态(国族)的。这可能是状态定义:

What we would need is a 'root' state. It will be the super parent of any other state (states family). This could be the state definition:

$stateProvider
  .state('root', {
      abstract: true,
      templateUrl: 'layout.tpl.html',
      controller: MyNamespace.RootCtrl,
  })

  .state('login', {
      parent: "root",
      url: "/login",
      templateUrl: 'tpl.html',
      controller: MyNamespace.LoginCtrl,
  })
  .state('home', {
      parent: "root",
      url: "/home",
      templateUrl: 'tpl.html',
      controller: MyNamespace.HomeCtrl,
  })

甚至一些其他国家的层次结构将与'根'状态下启动:

$stateProvider
  .state('parent', {
      parent: "root",
      url: "/parent",
      templateUrl: 'tpl.html',
      controller: MyNamespace.ParentCtrl
  })
  .state('parent.child1', { 
      url: "/child1",
      templateUrl: 'tpl.html',
      controller: MyNamespace.Child1Ctrl
  })
  .state('parent.child2', { 
      url: "/child2",
      templateUrl: 'tpl.html',
      controller: MyNamespace.Child2Ctrl
  })

我们可以看到很多的 控制器:... 被定义,在这里,他们是:

We can see many controllers:... being defined, and here they are:

module MyNamespace {
    // the real SUPER parent of all states
    // but it is about VIEW inheritance (its $scope)
    // not about controller hierarchy
    export class RootCtrl extends BaseController {
    }

    export class HomeCtrl extends BaseController {
    }
    export class LoginCtrl extends BaseController {
    }
    export class ParentCtrl extends BaseController {
    }
    export class Child1Ctrl extends BaseController {
    }
    export class Child2Ctrl extends BaseController {
    }
}

由于在片段评论中提及了 - 有继承,只是在code水平。传递 $范围由视图层次结构继承。

As mentioned in the snippet comment - there is inheritance, but just on a code level. The passed $scope is inherited by view hierarchy.

在视图层次结构的第一个控制器是 RootCtrl 这实际上将是唯一的,谁将会分配(创建)共享参考模型的 rootSetting:{}

The first controller in the view hierarchy is RootCtrl which will in fact be the only, who will assign (create) the shared reference model rootSetting : {}

和他们都获得从这一个控制器的基础:

And they all derive from this one controller base:

module MyNamespace {
    export interface IRootSetting {
        hideNavbar: boolean;
    }
    export interface IMyRootScope extends ng.IScope {
        rootSetting: IRootSetting
    } 
    export interface IBaseScope extends IMyRootScope {

    }
    export class BaseController {
        public hideNavbar: boolean;
        static $inject = ['$scope', '$state'];

        constructor(public $scope: IBaseScope, 
                 protected $state: ng.ui.IStateService) {

                  // will be in fact assigned in the RootCtrl only
                  // all others (children) will get that reference
                  // via scope inheritance
                  $scope.rootSetting = $scope.rootSetting || {hideNavbar: false}; 

            if ($state.current.url === '/login') {
                this.$scope.rootSetting.hideNavbar = true;
            } else {
                this.$scope.rootSetting.hideNavbar = false;
            }
        }
    }
}

有了这样的地方,这个根模板:

Having that in place, with this root template:

<div>      
  <div ng-if="!rootSetting.hideNavbar"> 
   ... // navbar
  </div>      

  <div ui-view="">
      // standard content of child views
  </div>      
</div>

我们可以看到,在这里我们评估共享参考模型的 rootSetting ,并将其属性 hideNavbar

We can see, that here we evaluate the shared reference model rootSetting and its property hideNavbar

这是 视图继承 即将UI-路由器的真正的优势。

This is the real advantages of view inheritance coming with UI-Router.

检查它在行动这里

这篇关于角文摘周期是运行,但NG绑定值不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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