4

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

我通常使用服务来完成这项任务并开始创建一个 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 上

4

1 回答 1

9

当 Angular 看到

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

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

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

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

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

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

这也解释了为什么setActivePersonWorks()有效——它不分配新的对象引用。

于 2013-05-09T15:51:15.330 回答