【问题标题】:how to avoid duplicate items with ng-repeat and drop in angularjs?如何避免使用 ng-repeat 和放入 angularjs 的重复项目?
【发布时间】:2016-10-07 07:26:17
【问题描述】:

你能告诉我一些问题的正确方法吗? 我有下一个情况:

1.我从服务器加载项目列表并在此处的容器中使用 ng-repeat 列出它:

<div layout="column" id={{vm.folderId}}container flex layout-align="start center" class='container' dragula='"first-bag"'>
   <div id={{item.id}}child class="md-whiteframe-5dp capitalize itemsInList" layout="column"  ng-repeat="item in vm.workItems | filter:search">
      <div layout="column" flex >
         <div class="workItemName">{{vm.getWorkItemName(item.metadata)}}</div>
         <div class="workItemDescription">{{vm.getWorkItemDescription(item.metadata)}}</div>
      </div>
   </div>
</div>

假设我们列出了下一个列表:

item_1
item_2
item_3
item_4

然后我将另一个元素放入此容器 ITEM_5。 在我放弃服务器后给我新列表:item_1 - item_2 - item_3 - item_4 - item_5 我在这里更新我的vm.workItems

if (data.ok) {
    if (data.content.items.length != vm.workItems.length) {
        vm.workItems = data.content.items; //from server
        SharedDataService.setLastUpdateTimeStamp(SharedDataService.getNewUpdateTimeStamp());
    }
}

在 ng-repeat 新鲜项目之后,它还会查看列表中删除的元素。所以最后我有:

item_1 //ng-repeated
item_2 //ng-repeated
item_3 //ng-repeated
item_4 //ng-repeated
item_5 //ng-repeated
item_5 //droped element

如何避免这种情况?有正常的解决办法吗?

更新。我删除元素,当它被删除时,我向服务器发出请求以将新项目添加到列表中:

  $scope.$on('first-bag.drop', function (e, el, container) {
        var elementId = parseInt(el[0].id);
        var newContainerId = parseInt(container[0].id);
        var newPrevElementId;
        var newPrevElement = document.getElementById(el[0].id).previousElementSibling;

        if(newPrevElement) {
            newPrevElementId = parseInt(newPrevElement.getAttribute('id'));
        } else  if(!newPrevElement)  {
            newPrevElementId = newContainerId;
        }

        if(exContainerId != newContainerId) {
            WebSocketService.addItem(elementId, exContainerId,
}
}

【问题讨论】:

标签: angularjs angularjs-ng-repeat


【解决方案1】:

你可以的

ng-repeat="item in vm.workItems track by item.id | filter:search"

如果每个项目都有一个唯一的 ID(或一些唯一的属性),并且如果您使用 track by ID,那么即使服务器返回以前的项目并添加了新项目,DOM 也不会重新渲染,只会重新渲染项目将被添加到 DOM。

Plunker(看看控制台)

ng-repeat 在对象列表中重复时将$$hashkey 属性添加到每个 对象。

当您的服务器返回新数据时,尽管已经存在对象,因为新数据(每个对象)中不包含 $$hashkey 属性,ng-repeat 重新渲染然后认为它们是新对象。

如果您使用track by ID,那么ng-repeat 不会添加$$hashkey 属性,它会使用ID 跟踪每个项目。因此,即使服务器再次返回相同的数据,因为 ID 匹配,ng-repeat 不会重复它们。如果有新的 ID,那么它会呈现给 DOM。

看看这个博客post

【讨论】:

  • 我猜应该这样吗? ng-repeat="vm.workItems 中的项目按索引跟踪"
  • @AmitKarnik 我不是 100% 确定,但 track by $index 使用数组中对象的位置。如果相同的数据以不同的顺序再次来自服务器,则可能存在一些问题。但是,有了 ID,无论订单是什么,您都可以始终确定。
  • 我会尝试使用它。希望不会得到额外的 DOM 元素
  • 抱歉错过了 '$' ,感谢您的澄清。
  • 仍然渲染额外的 dom :( 我用过:
【解决方案2】:

在你的函数中试试这个:

let data = data.content.items;
let temp = [];
data.forEach(function(item) {
    if (temp.indexOf(item) === -1) {
    temp.push(item);
  }
});
vm.workItems = temp;

希望这会有所帮助。

【讨论】:

  • 同理。它会在删除 DOM 元素之前列出通过 ng-repeat 接收到的项目。但感谢您的尝试。
猜你喜欢
  • 2016-04-16
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 2015-06-19
  • 2014-07-11
  • 1970-01-01
  • 2014-04-14
  • 1970-01-01
相关资源
最近更新 更多