【问题标题】:How to easily determine what's added/removed in a $scope.$watch?如何轻松确定 $scope.$watch 中添加/删除的内容?
【发布时间】:2014-09-03 16:36:57
【问题描述】:

我的任务是在 Angular 指令中包装一个 JQuery 样式的 UI 组件。我已经完成了任务,但它看起来相当丑陋。底层组件的 API 只有 addremove 用于控制项目列表的方法。我唯一能想到的就是使用scope.$watchCollection 观察传递给我的指令的双向绑定变量,然后遍历新旧参数以确定添加或删除的内容,然后调用添加/删除 API 调用在底层组件上。这行得通,但我很好奇是否有更好的方法来实现这一点。代码令人毛骨悚然,令人困惑。

这里是该组件在其自然栖息地的最小演示:

http://codepen.io/Chevex/pen/ofGeB?editors=101

您可以看到该组件是在一个元素上实例化的,该元素具有标记内列表中的项目。然后该组件返回一个 API 以添加/删除单个项目。请注意,在我们的实际应用程序中,我无法控制底层组件,并且实际组件的功能远远超过我的演示组件(可以很容易地用 ng-repeat 重写)。

这是我的指令包装器的最小演示:

http://codepen.io/Chevex/pen/LDgCF?editors=101

这很好用,并使用 jquery 样式的组件模拟双向绑定变量,该组件只有单个项目的添加/删除方法。我想知道是否有更好的方法来确定$watchCollection 中的新/删除项目。

  // Watch items for changes.
  scope.$watchCollection('items', function (newItemList, oldItemList) {
    // Iterate over the newItemList and determine what items are new.
    if (newItemList) {
      newItemList.forEach(function (newItem) {
        var addItem = true;
        if (oldItemList) {
          oldItemList.forEach(function (oldItem) {
            if (newItem === oldItem) {
              addItem = false;
            }            
          });
        }
        if (addItem) {
          listApi.addItem(newItem);
        }
      });
    }
    // Iterate over the oldItemList and determine what was removed.
    if (oldItemList) {
      oldItemList.forEach(function (oldItem, oldItemIndex) {
        var removeItem = true;
        if (newItemList) {
          newItemList.forEach(function (newItem) {
            if (oldItem === newItem) {
              removeItem = false;
            }
          });
        }
        if (removeItem) {
          listApi.removeItem(oldItemIndex);
        }
      });
    }
  });

所有这些只是为了确定当集合发生变化时应该使用组件 API 添加或删除什么。这是最好的方法吗?我问是因为我发现自己反复编写类似的逻辑,并想知道是否有更合适和/或更简单的方法来做到这一点。

【问题讨论】:

    标签: javascript jquery angularjs data-binding angularjs-directive


    【解决方案1】:

    你可以这样使用:

    Array.prototype.diff = function(arr) {
        return this.filter(function(el) { return arr.indexOf(el) < 0; });
    };
    
    var addedItems = newItemList.diff(oldItemList);
    var removedItems = oldItemList.diff(newItemList);
    

    【讨论】:

    • 简洁优雅。即使性能没有更快,至少代码要简单得多。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-28
    • 1970-01-01
    相关资源
    最近更新 更多