$ watch上的$ digest错误模型的更改

时间:2015-08-06 11:02:37

标签: javascript angularjs

我的应用程序通过API接收来自SSE(服务器发送事件)的项目更新。

我所拥有的是一个寻找此更改的主控制器:

if (!!window.EventSource) {
  var source = new EventSource('/items/updates');
} else {
  console.log('SSE not supported');
}

source.addEventListener('items', function (e) {
  var data = JSON.parse(e.data);
  Items.updateOneItem(data);
  $scope.$digest();
}, false);

项目是处理更改的服务工厂:

App.factory('Items', function () {

    var items = {};
    // previous and updated item
    var previousItemState = null;
    var updatedItem = null;

    items.list = [];

    items.getUpdatedItem = function () {
        return {
            previous: previousItemState,
            updated: updatedItem
        };
    };

    items.updateOneItem = function (item) {
        var i = $.map(items.list, function (e, i) {
            if (e !== null) {
                if (e.id === item.id) {
                    return i;
                }
            }
        });
        previousItemState = items.list[i];
        items.list[i] = item;
        updatedItem = item;
    };

    return items;

});

基本上在这项服务中,我存储了这些项目,我正在尝试检查项目是否已更新以及项目模型中究竟有哪些更改。

在我的控制器中我正在看这个并做我的控制,或者我正在尝试这样做:

$scope.$watch(Items.getUpdatedItem, function (item) {
    if (item.previous !== null && item.updated !== null) {
        // do my controls on previous and updated item...
    }
});

我发生的错误是这样的:

Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! [...]

我尝试从我的Items服务中返回一个单独的值并且它工作正常但我只收到更新的项目而且我不知道如何检查项目的更改:

items.getUpdatedItem = function () {
    return updatedItem;
};

我的问题是:

  • 为什么我无法从服务方法返回对象?
  • 在这种情况下,为了查看更改,使用上一个和更新项目的最佳做法是什么?

干杯

1 个答案:

答案 0 :(得分:0)

首先,您不应该手动运行$digest()。在$timeout中包含您需要摘要的代码。

第二件事,传递你的对象是正确的:

items.getUpdatedItem = function () {
    return updatedItem;
};

您在$watch中访问旧版和新版时遇到的问题很容易解决。传递给$watch的第二个参数是实际使用two arguments的函数:

$scope.$watch(Items.getUpdatedItem, function (newItem, oldItem) {
    if (oldItem !== newItem) {
        // do my controls on previous and updated item...
    }
});