Javascript 如何替换使用 ng-repeat 显示的数组中的对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29947176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:22:52  来源:igfitidea点击:

How can I replace an object in array that is displayed using ng-repeat?

javascriptangularjsangularjs-ng-repeat

提问by gusper

I have an array of items that is displayed in a table using ng-repeat. When you click on an item, that item is pulled from the server and the table should then be updated with the updated item.

我有一组使用 ng-repeat 显示在表格中的项目。当您单击一个项目时,该项目将从服务器中拉出,然后表格应使用更新的项目进行更新。

Function to get the updated item when clicking on an item in the table:

单击表格中的项目时获取更新项目的函数:

$scope.getUpdatedItem = function(item){
    itemService.getItem(item).then(
        function(updatedItem){
            item = updatedItem;
        },
        function(error){
            //Handle error
        }
    );
};

I'm displaying the items using:

我正在使用以下方法显示项目:

<tr ng-repeat="item in myItems">

The problem: The item in the table is never updated.

问题:表中的项目永远不会更新。

What's the best way to update the item in the ng-repeat? Can i use "track by $index" in the ng-repeat for this? Or do I have to iterate over myItems to find the item I want to replace?

更新 ng-repeat 中项目的最佳方法是什么?我可以在 ng-repeat 中使用“按 $index 跟踪”吗?还是我必须遍历 myItems 才能找到要替换的项目?

Update:

更新:

A possible solution is instead of using

一个可能的解决方案是而不是使用

item = updatedItem,

item = updatedItem,

to use:

使用:

var index = $scope.myItems.indexOf(item);
$scope.myItems[index] = updateItem;

However, I feel that there should be a "cleaner" way of doing this.

但是,我觉得应该有一种“更清洁”的方法来做到这一点。

采纳答案by eladcon

There isn't a much cleaner way (then your update). As you noticed, when you change itemin your callback function you change the local reference, and not the original item in the array.

没有更干净的方法(然后是您的更新)。正如您所注意到的,当您更改item回调函数时,您会更改本地引用,而不是数组中的原始项目。

You can improve this a bit by using the $indexfrom the ng-repeat, instead of calculating it yourself:

您可以通过使用$indexfrom来改进这一点ng-repeat,而不是自己计算:

<div ng-click="getUpdatedItem(item, $index)"> </div>

And in your controller:

在您的控制器中:

$scope.getUpdatedItem = function(item, index){
    itemService.getItem(item).then(
    function(updatedItem){
        $scope.myItems[index] = updateItem;
    },
    function(error){
        //Handle error
    }
    );
};

You can also use angular.copyinstead but it's much less efficient:

您也可以angular.copy改用,但效率要低得多:

function(updatedItem){
    angular.copy(updateItem, item);
},

回答by Eloims

If I understand your problem properly

如果我正确理解你的问题

could something like this work?

可以这样工作吗?

<!-- template code -->
<table>
    ...
    <tr ng-repeat="(index, item) in items">
        <td>{{item.name}}</td>
        <td>
             {{item.detail}}
             <button ng-if="!item.detail" ng-click="loadItem(index)">
        </td>
    </tr>
</table>

// Controller Code
$scope.items = [...]
$scope.loadItem = function(index){
    itemService.getItemDetail($scope.items[index]).then(function(itemDetail){
        $scope.items[index].detail = itemDetail;
    });
};

回答by Michael Hays

itemmay start as a reference to an item in your list, but when you say:

item可以作为对列表中某个项目的引用开始,但是当您说:

item = updatedItem;

You reseat that binding -- you are no longer referring to the item in the list, but to the disconnected one that was returned in your promise. Either you will need to modify the item, like so:

您重新设置绑定——您不再指列表中的项目,而是指在您的承诺中返回的断开连接的项目。您将需要修改该项目,如下所示:

function(updatedItem){
  item.varA = updatedItem.varA
  item.varB = updatedItem.varB
  ...
}

Or, if it gets too hairy, you might consider an item array that looks more like this:

或者,如果它变得太多毛茸茸,你可以考虑一个看起来更像这样的项目数组:

var items = [ 
  { data: item1 },
  { data: item2 },
  { data: item3 }
};

At which point your update function will look like this:

此时您的更新函数将如下所示:

function(updatedItem){
    item.data = updatedItem;
},

回答by Sean

I've just spent hours on this issue. I couldn't use the $indexsolution from @eladcon, as my ng-repeatalso used a filter, to the index isn't correct if the rows/items are filtered.

我刚刚在这个问题上花了几个小时。我无法使用$index来自@eladcon的解决方案,因为我ng-repeat也使用了过滤器,如果行/项目被过滤,则索引不正确。

I thought I would be able to just do this:

我以为我可以这样做:

$filter('filter')($scope.rows, {id: 1})[0] = newItem;

but that doesn't work.

但这不起作用。

I ended up iterating the array until I found a match, and then using the $indexfrom the iteration (not from the ng-repeat) to set the array item to the new item.

我最终迭代数组,直到找到匹配项,然后使用$index来自迭代(而不是来自ng-repeat)将数组项设置为新项。

// i'm looking to replace/update where id = 1
angular.forEach($scope.rows, function(row, $index) {
  if (row.id === 1) {
    $scope.rows[$index] = newItem;
  }
})

See here: https://codepen.io/anon/pen/NpVwoq?editors=0011

见这里:https: //codepen.io/anon/pen/NpVwoq?editors=0011