控制器之间共享服务的脏检查,一种方法有效,另一种方法无效

Dirty checking with shared service between controllers, One way works the other does not?

本文关键字:方法 无效 一种 有效 另一种 共享 之间 服务 检查 控制器      更新时间:2023-09-26

在试图回答关于在两个单独的控制器之间共享数据的问题时,我遇到了一个问题。

我通常使用服务来完成这个任务,并开始创建一个jsfiddle,但我无法让它工作。

经过一些调试,如果我在setActivePersonWorks(person)中动态创建属性,脏检查工作,第二个控制器显示正确的值。

如果我在setActivePersonDoesNotWork()中赋值,它没有。

如果我使用$timeout(),我能够验证DataService.badPerson确实包含正确的数据。

我做错了什么吗?我想如果你用$apply()做点什么,它会正常工作,但是为什么动态地创建值会导致事情正常工作呢?

工作的例子:

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);
}

<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>
在jsfiddle

当Angular看到

<h1>Does Not Work: {{badPerson.name}}</h1>

在对象badPerson上设置$watch。看看您的控制器,$scope.badPerson是对对象DataService.badPerson的引用。到目前为止一切都很好……问题发生在这里:

setActivePersonDoesNotWork: function (person) {
    People.badPerson = person;
}

当这个函数执行时,badPerson被分配了一个新的/不同的对象引用,但是控制器仍然$监视旧的/原始的对象引用。

修复方法是使用angular.copy()来更新现有的badPerson对象,而不是分配一个新的引用:

setActivePersonDoesNotWork: function (person) {
    angular.copy(person, People.badPerson);
}

这也解释了为什么setActivePersonWorks()工作——它不分配一个新的对象引用