【问题标题】:Dirty checking with shared service between controllers, One way works the other does not?使用控制器之间的共享服务进行脏检查,一种方法有效,另一种方法无效?
【发布时间】:2013-05-04 03:16:37
【问题描述】:

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

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

On jsfiddle

【问题讨论】:

    标签: javascript angularjs angularjs-service


    【解决方案1】:

    当 Angular 看到时

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

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

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

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

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

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

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

    【讨论】:

    • 太棒了!感谢您的修复和解释。
    猜你喜欢
    • 2019-07-13
    • 2016-06-05
    • 1970-01-01
    • 2014-02-04
    • 2013-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多