AngularJS对象字段不是从孩子的指令更新 [英] AngularJS object field not updating from child directive
问题描述
我有一个父控制器 A
,谁的范围包含的对象重新presenting其状态。所以,我可以访问 state.status
从 A
的范围,以更新其状态。
我有一个孩子的指令, B
,谁拥有绑定到字段 A
的状态对象。这让我更新的 A
从 B
。
下面是简化code为我控制器 A
:
angular.module(对myApp)。控制器('A',函数($范围){ $ scope.state = {
状态:全部
};
函数DoSomething的(){
的console.log(state.status);
}});
和用于指示 B
:
angular.module('对myApp')。指令('B',函数(){ 返回{
templateUrl:B.html',
范围: {
selectedStatus:'=地位,
的onChange:'=的onChange
},
链接:功能(范围,元素,ATTRS){
scope.setStatus =功能(状态){
scope.selectedStatus =状态;
scope.onChange();
};
}
}});
在DOM:
< B状态=上变化=DoSomething的/&GTstate.status
当我称之为 setStatus()
从我的指令中 B
,我希望我所提出的修改对象由 DoSomething的()
被调用的时候被传播。但是,的console.log()
输出是旧的价值,不是我只是它更新到。在修改完成,只是不够快。
我试过打电话给 $范围。$适用()
但是它抱怨一个 $范围之内。$适用()
通话了。 (
什么是对付它的最好方法?
依我看你是一个有点困惑是如何工作的。
当你做的东西像状态=state.status
和更改状态的指令里面,变化将只执行摘要周期后应用,但在你的情况下,您尝试输出 state.status
前完成消化,所以它不使用同步的值。
有解决这几个方面:
- 通话
scope.onChange
在$超时
- 通过完整的对象
状态
而不是state.status
- 使用
范围。$父
访问,可以定义父范围状态
对象
angular.module(对myApp,[])。指令('BB' ,功能($超时){\r
返回{\r
模板:'< DIV>< DIV NG点击=setStatus1(\\'状态1 \\')大于1。所选状态:{{selectedStatus}}< / DIV>< DIV NG点击=setStatus2(\\'STATUS2 \\')大于2。所选状态:{{selectedStatus}}< / DIV>< DIV NG点击=setStatus3(\\'STATUS3 \\')→3。所选状态:{{selectedStatus}}< / DIV>< / DIV>,\r
范围: {\r
selectedStatus:'=地位,\r
的onChange:'=的onChange',\r
状态:'='\r
},\r
链接:功能(范围,元素,ATTRS){\r
scope.setStatus1 =功能(状态){\r
的console.log('setstatus1');\r
scope.selectedStatus =状态;\r
$超时(函数(){\r
scope.onChange();\r
});\r
};\r
scope.setStatus2 =功能(状态){\r
的console.log('setstatus2');\r
scope.selectedStatus =状态;\r
scope.state.status =状态;\r
scope.onChange();\r
};\r
scope.setStatus3 =功能(状态){\r
的console.log('setstatus3');\r
scope.selectedStatus =状态;\r
。范围$ parent.state.status =状态;\r
scope.onChange();\r
};\r
}\r
}\r
\r
})。控制器('A',函数($范围){\r
\r
$ scope.state = {\r
状态:全部\r
};\r
$ scope.doSomething = DoSomething的;\r
\r
函数DoSomething的(){\r
的console.log('DoSomething的:',$ scope.state.status);\r
}\r
\r
});
\r
<脚本数据需要=angular.js@1.4.0-rc .1数据semver =1.4.0-RC.1SRC =的https://$c$c.angularjs.org/1.3.8/angular.js>&下; /脚本>\r
< DIV NG-应用=对myAppNG控制器=A>\r
< BB状态=state.status状态的变化=DoSomething的&GT =状态;< / BB>\r
{{州}}\r
< / DIV>
\r
I have a parent controller A
, who's scope contains an object representing its state. So I can access state.status
from A
's scope to update its status.
I have a child directive, B
, who has a binding to a field in A
's status object. This allows me to update A
's state from B
.
Here's the simplified code for my controller A
:
angular.module("myApp").controller('A', function($scope){
$scope.state = {
"status": "All"
};
function doSomething() {
console.log(state.status);
}
});
And for the directive B
:
angular.module('myApp').directive('B', function () {
return {
templateUrl: 'B.html',
scope: {
selectedStatus: '=status',
onChange: '=onChange'
},
link: function (scope, element, attrs) {
scope.setStatus = function(status) {
scope.selectedStatus = status;
scope.onChange();
};
}
}
});
In the DOM:
<B status="state.status" on-change="doSomething" />
When I call setStatus()
from within my directive B
, I expect the changes I've made to the object to be propagated by the time doSomething()
is called. However, the console.log()
output is of the old value, not what I've just updated it to. The change is made, just not fast enough.
I've tried to call $scope.$apply()
however it complains that it's within a $scope.$apply()
call already. :(
What's the best way to deal with this?
Methinks you are a bit confused about how this works.
When you do something like status="state.status"
and change status inside a directive, changes will be applied only after executing the digest cycle, but in your case you try to output state.status
before finishing the digest, so it doesn't use the synchronized value.
There are a few ways to solve this:
- call
scope.onChange
inside$timeout
- pass full object
state
insteadstate.status
- use
scope.$parent
for access to parent scope where you definestate
object
angular.module("myApp", []).directive('bb', function($timeout) {
return {
template: '<div><div ng-click="setStatus1(\'status1\')">1. Selected status: {{selectedStatus}}</div><div ng-click="setStatus2(\'status2\')">2. Selected status: {{selectedStatus}}</div><div ng-click="setStatus3(\'status3\')">3. Selected status: {{selectedStatus}}</div></div>',
scope: {
selectedStatus: '=status',
onChange: '=onChange',
state: '='
},
link: function(scope, element, attrs) {
scope.setStatus1 = function(status) {
console.log('setstatus1');
scope.selectedStatus = status;
$timeout(function() {
scope.onChange();
});
};
scope.setStatus2 = function(status) {
console.log('setstatus2');
scope.selectedStatus = status;
scope.state.status = status;
scope.onChange();
};
scope.setStatus3 = function(status) {
console.log('setstatus3');
scope.selectedStatus = status;
scope.$parent.state.status = status;
scope.onChange();
};
}
}
}).controller('A', function($scope) {
$scope.state = {
"status": "All"
};
$scope.doSomething = doSomething;
function doSomething() {
console.log('doSomething: ', $scope.state.status);
}
});
<script data-require="angular.js@1.4.0-rc.1" data-semver="1.4.0-rc.1" src="https://code.angularjs.org/1.3.8/angular.js"></script>
<div ng-app="myApp" ng-controller="A">
<bb status="state.status" state="state" on-change="doSomething"></bb>
{{state}}
</div>
这篇关于AngularJS对象字段不是从孩子的指令更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!