【问题标题】:How to control $scope.$watch iteration?如何控制 $scope.$watch 迭代?
【发布时间】:2015-02-18 02:24:33
【问题描述】:

我正在尝试控制 $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:

$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 以保存其位置状态,以便在浏览器关闭/刷新时它仍将保留其会话/职位。也许您对我将如何解决这个问题有所了解?谢谢!

【问题讨论】:

  • 你正在导致一个无限循环,因为每次$scope.dashboards 变量更改并且 $watcher 被触发时,你都会再次更改它。
  • @NewDev 有什么你可能知道的解决方法吗?
  • 我不确定您要做什么以及为什么每次更改 $scope.dashboards 时都需要更改 $scope.dashboards。
  • 尽量避免在 else 语句中更改 $scope.dashboards 的值。正如其他人所说,它正在触发无限循环
  • 我要做的是获取 $scope.dashboards 对象,该对象存储在我的仪表板上的小部件的位置中。因此,我正在增加 id,并且该 id 将用作我的 json 对象已更改的标识符,可以说有人将小部件拖放到另一个地方。

标签: javascript angularjs angularjs-scope gridster angularjs-watch


【解决方案1】:

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

您应该避免使用$watch 作为更新$scope.dashboards.id 的触发器,并使用导致小部件更改的实际触发器。 (题外话,但是id 属性的使用有点尴尬 - id 有一个非常具体的含义,我会将其更改为“版本”或类似的东西)

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

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

【讨论】:

    【解决方案2】:

    您可以使用的方法的大致轮廓如下:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-26
      • 2013-05-12
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 2015-04-05
      • 1970-01-01
      相关资源
      最近更新 更多