控制器之间共享服务的脏检查,一种方法有效,另一种方法无效? [英] Dirty checking with shared service between controllers, One way works the other does not?
问题描述
在尝试回答有关在两个独立控制器之间共享数据的问题时,我遇到了一个问题.
我通常使用服务来完成这项任务并开始创建一个 jsfiddle,但我无法让它工作.
如果我在 setActivePersonWorks(person)
中动态创建属性,经过一些调试后,脏检查起作用了,第二个控制器显示了正确的值.
如果我在 setActivePersonDoesNotWork()
中分配了值,它没有.
如果我使用 $timeout()
,我能够验证 DataService.badPerson
确实包含正确的数据.
我做错了吗?我想如果你用 $apply()
做一些事情它会正常工作,但是为什么动态创建值会导致事情正常工作?
工作示例:
var myTest = angular.module("MyTest", []);myTest.factory("DataService", function () {var 人 = {好人:{},坏人: {},setActivePersonWorks:函数(人){People.goodPerson.name = person.name;People.goodPerson.id = person.id;},setActivePersonDoesNotWork:函数(人){People.badPerson = 人;}};返回人;});函数 ViewController($scope, DataService, $timeout) {$超时(函数(){DataService.setActivePersonWorks({编号:1,名称:《好记号》});DataService.setActivePersonDoesNotWork({编号:2,名称:《坏标记》});}, 1000);}function DetailController($scope, DataService, $timeout) {$scope.goodPerson = DataService.goodPerson;$scope.badPerson = DataService.badPerson;$超时(功能(){$scope.message = "DataService 的值是:" + DataService.badPerson.name + " 但 $scope.badPerson 是 " + $scope.badPerson.name;}, 2000);}
<div ng-controller="ViewController"></div><div ng-controller="DetailController"><h1>作品:{{goodPerson.name}}</h1><h1>不起作用:{{badPerson.name}}</h1>{{信息}}
当 Angular 看到
不起作用:{{badPerson.name}}
它在对象 badPerson
上设置了一个 $watch.查看您的控制器,$scope.badPerson
是对对象 DataService.badPerson
的引用.到目前为止一切都很好......问题发生在这里:
setActivePersonDoesNotWork:函数(人){People.badPerson = 人;}
当这个函数执行时,badPerson
被分配了一个新的/不同的对象引用,但控制器仍然在 $watching 旧的/原始对象引用.
修复方法是使用 angular.copy() 来更新现有的 badPerson
对象,而不是分配一个新的引用:
setActivePersonDoesNotWork:函数(人){angular.copy(person, People.badPerson);}
这也解释了为什么 setActivePersonWorks()
起作用——它不分配新的对象引用.
While attempting to answer a question regarding sharing data between two separate controllers I ran into a question .
I usually use services for for this task and began to create a jsfiddle, but I could not get it to work.
After a bit of debugging if I created the properties dynamically in setActivePersonWorks(person)
the dirty checking worked and the second controller showed the correct value.
If I assigned the value in setActivePersonDoesNotWork()
it did not.
If I used $timeout()
I was able to verify that DataService.badPerson
did indeed contain the correct data.
Am I doing something wrong? I guess if you do something with $apply()
it will work correctly, but why does creating the values dynamically cause things to just work?
Working Example:
var myTest = angular.module("MyTest", []);
myTest.factory("DataService", function () {
var People = {
goodPerson: {},
badPerson: {},
setActivePersonWorks: function (person) {
People.goodPerson.name = person.name;
People.goodPerson.id = person.id;
},
setActivePersonDoesNotWork: function (person) {
People.badPerson = person;
}
};
return People;
});
function ViewController($scope, DataService, $timeout) {
$timeout(function () {
DataService.setActivePersonWorks({
id: 1,
name: "Good Mark"
});
DataService.setActivePersonDoesNotWork({
id: 2,
name: "Bad Mark"
});
}, 1000);
}
function DetailController($scope, DataService, $timeout) {
$scope.goodPerson = DataService.goodPerson;
$scope.badPerson = DataService.badPerson;
$timeout(function(){
$scope.message = "DataService has the value: " + DataService.badPerson.name + " but $scope.badPerson is " + $scope.badPerson.name;
}, 2000);
}
The <html/>
<div ng-app="MyTest">
<div ng-controller="ViewController"></div>
<div ng-controller="DetailController">
<h1>Works: {{goodPerson.name}}</h1>
<h1>Does Not Work: {{badPerson.name}}</h1>
{{message}}
</div>
</div>
When Angular sees
<h1>Does Not Work: {{badPerson.name}}</h1>
it sets up a $watch on object badPerson
. Looking at your controller, $scope.badPerson
is a reference to object DataService.badPerson
. All is fine so far... the problem happens here:
setActivePersonDoesNotWork: function (person) {
People.badPerson = person;
}
When this function executes, badPerson
is assigned a new/different object reference, but the controller is still $watching the old/original object reference.
The fix is to use angular.copy() to update the existing badPerson
object, rather than assigning a new reference:
setActivePersonDoesNotWork: function (person) {
angular.copy(person, People.badPerson);
}
This also explains why setActivePersonWorks()
works -- it does not assign a new object reference.
这篇关于控制器之间共享服务的脏检查,一种方法有效,另一种方法无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!