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

$digest error on $watch for changes in model

本文关键字:模型 错误 watch 上的 digest      更新时间:2023-09-26

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

我所拥有的是一个寻找这些变化的主控制器:

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

Items是处理更改的服务工厂:

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.getUpdatedItem = function () {
    return updatedItem;
};

我的问题是:

    为什么我不能从我的服务方法返回一个对象?
  • 在这种情况下,拥有先前和更新的项目以查看更改的最佳实践是什么?

欢呼

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

第二件事,像这样传递你的对象是正确的:
items.getUpdatedItem = function () {
    return updatedItem;
};

$watch中访问新旧版本的问题很容易解决。传递给$watch的第二个参数是一个实际使用两个参数的函数:

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