如何控制$scope.$watch迭代

How to control $scope.$watch iteration?

本文关键字:scope watch 迭代 控制 何控制      更新时间:2023-09-26

我正在尝试控制$scope.$watch函数。目前,我的迭代有一个无限循环。

$scope.$watch('dashboards', function(newVal, oldVal) {
    if (newVal !== oldVal) {
        $scope.dashboard = $localStorage.sample;
        $scope.dashboards['1'].id = $scope.dashboards[1].id + 1;
        $localStorage.sample = $scope.dashboards[1];
        console.log('newval: '+$scope.dashboards['1'].id);
    } else {
        $scope.$storage = $localStorage;
        $localStorage.sample = $scope.dashboards[1];
        $scope.dashboard = $localStorage.sample;
        $scope.dashboards['1'].id = $scope.dashboards[1].id.length + 1;
        $localStorage.sample = $scope.dashboards[1];
    console.log('oldval: '+$scope.dashboards['1'].id);
    }
}, true);

这是我的范围仪表板:

$scope.dashboards = {
        '1' : {
            id : '1',
            widgets : [{
                code : "bla1.html",
                col : 0,
                row : 0,
                sizeY : 1,
                sizeX : 2,
                title : "Bla1"
            }, {
                code : "bla2.html",
                col : 2,
                row : 0,
                sizeY : 2,
                sizeX : 2,
                title : "Bla2"
            }, {
                code : "bla3.html",
                col : 0,
                row : 4,
                sizeY : 1.5,
                sizeX : 2,
                title : "Bla3"
            }
}

我试图实现的是,每次我的 $scope.dashboards 中小部件的位置发生变化时,我都会在 localStorage 中存储一个新 ID 以保存其位置状态,以便在浏览器关闭/刷新时它仍将保留其会话/位置。也许您对我将如何解决这个问题有一个想法?谢谢!

问题的根源在于,通过在$watcher($scope.dashboards(中为$watched的值分配不同的值,会导致无限循环。

应避免使用 $watch 作为触发器来更新$scope.dashboards.id,并使用导致小组件更改的实际触发器。(题外话,但属性id的使用有点尴尬 - id 有一个非常具体的含义,我会把它改成"版本"或类似的东西(

或者,另一种选择是仅$watch widgets属性,而不是深度监视dashboards

$scope.$watch("dashboards['1'].widgets", function(newVal, oldVal){
 ...
}, true);

您可以使用的方法的粗略概述如下:

var modificationInProgress = false;
$scope.$watch('dashboards', function(newVal, oldVal) {
  if (!modificationInProgress) {
    modificationInProgress = true;
    // modify dashboards
  }
  $timeout(function() {
    modificationInProgress = false;
  }, 0);
});

如果您希望在同一刻度中多次修改仪表板,这可能会导致一些有趣的错误。但是,如果您只希望仪表板在每个刻度中修改一次(例如,当用户单击按钮时(,这应该有效。

但是 - 你的代码很奇怪。我认为重构它以避免监视和修改相同的变量可能是您最好的举措。例如,您可能希望监视不同的对象,并存储它们在单独对象上移动的次数,从而避免无限循环问题。