使用 Angular "track by $ index" 分页、过滤和排序不起作用

Using Angular "track by $ index" with pagination, filtering and sorting not working

我在 table 中尝试使用智能 Table 进行分页、过滤和搜索时遇到问题。

在将使用请求的 JSON 转换为对象时,我正在使用 table。在这种情况下,我做了:

$scope.estoque = JSON.parse(data.data);

当我需要包括分页、排序和搜索时,问题就来了。然后使用 Smart Table,直到那时它一直在为我提供我需要的东西。

如果要使用它的功能,我的 table 数组不能像以前那样是对象,它需要是 JSON。在这种情况下,格式如下:

 $scope.estoqueJSON = data.data;

[
  {
    "EstoqueId": 553,
    "DescricaoEstoque": null,
    "NomeMaterial": "Cabo de Fibra Óptica 04FO Multimodo - Indoor / Outdoor - 62,5/125 Furukawa",
    "CodigoMaterial": "100",
    "Ni": "",
    "QtdMaterial": 3.0,
    "QtdMin": 0.0,
    "Unidade": "m",
    "MaterialId": 1
  }
]

按照 Smart Table 文档中的教程,我创建了下面的 table:

<table st-table="estoqueStr" st-set-filter="myStrictFilter" class="table table-striped table-responsive">
                <thead style="text-align:center;">
                    <tr>
                        <th st-sort="CodigoMaterial" style="width:20px; font-weight:bold; text-align:center;">Código</th>
                        <th st-sort="Ni" style="width:20px; font-weight:bold; text-align:center;">Ni</th>
                        <th st-sort="NomeMaterial" style="width:20px; font-weight:bold; text-align:center;">Material</th>
                        <th st-sort="Unidade" style="width:20px; font-weight:bold; text-align:center;">UNI.</th>
                        <th st-sort="QtdMaterial" style="width:20px; font-weight:bold; text-align:center;">Qtd</th>
                        <th st-sort="QtdMin" style="width:20px; font-weight:bold; text-align:center;">Qtd Min.</th>
                    </tr>
                    <tr>
                        <th style="width:20px;">
                            <input style="text-align:center;" st-search="CodigoMaterial" placeholder="Código material" class="input-sm form-control" type="search" />
                        </th>
                        <th style="width:20px; text-align:center;">
                            <input style="text-align:center;" st-search="Ni" placeholder="Ni" class="input-sm form-control" type="search" />
                        </th>
                        <th style="width:auto; text-align:center;">
                            <input style="text-align:center;" st-search="NomeMaterial" placeholder="Nome material" class="input-sm form-control" type="search" />
                        </th>
                        <th style="width:10px; text-align:center;">
                            <input style="text-align:center;" st-search="Unidade" placeholder="Unidade" class="input-sm form-control" type="search" />
                        </th>
                        <th style="width:10px; text-align:center;">
                            <input style="text-align:center;" st-search="QtdMaterial" placeholder="Qtde atual" class="input-sm form-control" type="search" />
                        </th>
                        <th style="width:10px; text-align:center;">
                            <input style="text-align:center;" st-search="QtdMin" placeholder="Qtde mínima" class="input-sm form-control" type="search" />
                        </th>

                    </tr>
                </thead>
                <tbody id="" class="">
                    <tr ng-repeat="e in estoqueJSON | filter : paginate | orderBy:sortType:sortReverse | filter:searchField track by $index">
                        <td ng-repeat-start="item in e.value"></td>
                        <td style="text-align:center;">{{item.CodigoMaterial}}</td>
                        <td style="text-align:center;">{{item.Ni}}</td>
                        <td>{{item.NomeMaterial}}</td>
                        <td style="text-align:center;">{{item.Unidade}}</td>
                        <td style="text-align:right; color:black;">
                            <span e-form="tableform" editable-number="e.QtdMaterial" onbeforesave="checkQtdEstoque(e, $data)">{{item.QtdMaterial}}</span>
                        </td>
                        <td style="text-align-last:right; color:black;" ng-repeat-end>
                            <span editable-number="e.QtdMin" e-form="tableform" onbeforesave="checkQtdMin(e, $data)">{{item.QtdMin}}</span>
                        </td>

                    </tr>
                </tbody>
            </table>

我不知道为什么它没有在控制台中显示任何错误,也没有在我的 table 中显示 JSON 数据。谁能告诉我我做错了什么?

AngularJS: 1.3

更新

Ero 的回答是正确的,我只需要再次将我的数组转换为对象,然后使用 ng-repeat。我仍然使用 Smart Table 过滤器错误(对象数组不起作用),但我认为这是插件错误,我会在 github 论坛上查看。

因为您的 ng-repeat 超过了单个 <tr>,所以您不需要使用 ng-repeat-startng-repeat-end。封装的 <tr> 标签将重复它的内部 HTML。尝试取出这些标签并仅使用 item 来引用您当前的对象。我为您更改了以下 HTML(未经测试!):

<tbody id="" class="">
    <tr ng-repeat="item in estoqueJSON | filter : paginate | orderBy:sortType:sortReverse | filter:searchField track by $index">
        <td style="text-align:center;">{{item.CodigoMaterial}}</td>
        <td style="text-align:center;">{{item.Ni}}</td>
        <td>{{item.NomeMaterial}}</td>
        <td style="text-align:center;">{{item.Unidade}}</td>
        <td style="text-align:right; color:black;">
            <span e-form="tableform" editable-number="item.QtdMaterial" onbeforesave="checkQtdEstoque(item, $data)">{{item.QtdMaterial}}</span>
        </td>
        <td style="text-align-last:right; color:black;">
            <span editable-number="item.QtdMin" e-form="tableform" onbeforesave="checkQtdMin(item, $data)">{{item.QtdMin}}</span>
        </td>
   </tr>
</tbody>

由于对象具有唯一标识符 属性、EstoqueId,因此使用它来跟踪而不是 $index:

<tr ng-repeat="e in estoqueJSON | filter : paginate | orderBy:sortType:sortReverse | filter:searchField track by e.EstoqueId">

来自文档:

If you are working with objects that have a unique identifier property, you should track by this identifier instead of the object instance [or $index]. Should you reload your data later, ngRepeat will not have to rebuild the DOM elements for items it has already rendered, even if the JavaScript objects in the collection have been substituted for new ones. For large collections, this significantly improves rendering performance.

— AngularJS ng-repeat Directive API Reference - Tracking