我是AngularJS的新手。这是我的问题。
我有一个像var isStateA = false
这样的页面级变量。我已将此变量分配给我的控制器变量,如下所示:
var isStateA = false;
app.controller('AController',function($scope){
$scope.shouldShow = isStateA;
});
app.controller('BController',function($scope){
$scope.shouldShow = !isStateA;
});
shouldShow
属性会相应地绑定到ng-show
。
预期的行为是我将isStateA
更改为true
。两个控制器范围内的值应该改变,因此,它们应该执行显示/隐藏逻辑。
但上面的代码没有发生这种情况。我想知道是否有办法做到这一点?就像isStateA
值更改时一样,通知相关属性应用最新值?
谢谢
答案 0 :(得分:4)
你错了,因为你不明白
AngularJS知道应用程序中的值因观察者而发生了变化。观察者在很多地方被分配,但在你的情况下,你在模板中使用$ scope.shouldShow。更改$ scope.shouldShow的值将通过angular和work来获取,但更改isStateA不会,因为它们不是同一个变量。这是正确的解决方案:
// Your code
app.service('stateAService', function() {
this.isStateA = false;
})
app.controller('AController', function($scope, stateAService) {
$scope.stateAService = stateAService;
})
app.controller('BController', function($scope, stateAService) {
$scope.stateAService = stateAService;
})
// Template, controller A
<div ng-show="stateAService.isStateA">
</div>
// Template, controller B
<div ng-show="!stateAService.isStateA"></div>
// Some code, anywhere else in your app
app.controller('WhateverController', function($scope, stateAService) {
this.hideBAndShowA = function() {
stateAService.isStateA = true;
// The change to stateAService gets picked up by the watchers, all good
}
})
答案 1 :(得分:2)
Angular不会$ watch isStateA
变量,因此第二次更改不会被Angular“拾取”。
分配时:
$scope.shouldShow = isStateA;
您所做的就是将一个原始布尔值(按值)分配给范围变量。
你接近这个方法是一个不好的做法,但如果你坚持......
要解决此问题,您可以将$scope.shouldShow
设为函数:
app.controller('AController',function($scope){
$scope.shouldShow = function(){ return isStateA; };
});
app.controller('BController',function($scope){
$scope.shouldShow = function(){ return !isStateA; };
});
或对象(由@aj_r建议)。
但是,由于您需要让Angular知道发生了更改,因此无法使用。这是BAD PRACTICE部分(取自SO answer):
// assuming <body> is the root element of your Angular app
var $body = angular.element(document.body);
var $rootScope = $body.scope().$root;
$rootScope.$apply(function () {
isStateA = !isStateA;
});
答案 2 :(得分:1)
isStateA
按值传递到$scope.shouldShow
,表示该值已复制,且未创建任何引用。
有一个简单的解决方案,但我不要推荐它,因为它没有遵循AngularJS的正确模式。如果你想要,那么跳到这个答案的结尾。
您应该只从控制器内部更新$scope
变量(如果必须有DOM交互,则应该更新指令)。我不确定您要对此做些什么,但应该有一种方法来构建代码,以便您可以摆脱isStateA
,并直接在控制器中设置$scope.shouldShow = true
。为什么需要在2个不同的控制器中访问相同的范围变量?也许您应该将它们组合到一个公共控制器中,或创建一个可以注入两个控制器的服务/工厂。
简单(但不推荐)解决方案是使用对象创建引用:
var isStateA = { shouldShow: false };
app.controller('AController',function($scope){
$scope.state = isStateA;
});
// Now whenever you set isStateA.shouldShow, it should update the model and the view.
注意:如果您在控制器之外设置isStateA .shouldShow
,那么您的视图将不更新,因为Angular不知道它。因此,它不会进行消化循环。