1

我的任务是在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添加或删除什么。这是最好的方法吗?我问,因为我一直在发现自己反复写了类似的逻辑,并想知道是否可能有更合适和/或更简单的方法来做到这一点。

回答

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

优雅简洁明了。即使性能没有更快,至少代码要简单得多。谢谢。 – Chev 2014-09-03 18:36:23

相关问题