角文摘周期是运行,但NG绑定值不更新 [英] Angular Digest cycle being ran but ng-bind value not updating
问题描述
我有一个包含导航栏父视图,该视图里面我有一个<格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屋!