控制器之间共享服务的脏检查,一种方法有效,另一种方法无效? [英] Dirty checking with shared service between controllers, One way works the other does not?

查看:25
本文介绍了控制器之间共享服务的脏检查,一种方法有效,另一种方法无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

关于 jsfiddle

解决方案

当 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>

On jsfiddle

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆