Использование Angular "track by $ index" с разбивкой на страницы, фильтрацией и сортировкой не работает

У меня возникла проблема при попытке использовать Smart Table с подкачкой, фильтрацией и поиском в моей таблице.

Я работал с таблицей при преобразовании JSON, который потребовал запрос к объекту. В этом случае я сделал:

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

Проблема возникла, когда мне нужно было включить подкачку, сортировку и поиск. Затем с помощью Smart 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 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>

Я не знаю, почему он не показывает какую-либо ошибку в консоли, а также не отображает данные JSON в моей таблице. Может кто-нибудь сказать мне, что я делаю не так?

AngularJS: 1,3

ОБНОВИТЬ

Эро ответ был правильным, мне просто нужно снова преобразовать мой массив для объекта, а затем использовать ng-repeat. Я все еще с ошибкой Smart Table для фильтра (что не работает для массива объектов), но я думаю, что это ошибка плагина, и я проверю на форуме github.

2 ответа

Решение

Потому что ваш ng-repeat более одного <tr> вам не нужно использовать ng-repeat-start а также ng-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">

Из документов:

Если вы работаете с объектами, имеющими свойство уникального идентификатора, вы должны отслеживать этот идентификатор вместо экземпляра объекта [или $index]. Если вы перезагрузите свои данные позже, ngRepeat не нужно будет перестраивать элементы DOM для уже отрисованных элементов, даже если объекты JavaScript в коллекции были заменены новыми. Для больших коллекций это значительно повышает производительность рендеринга.

- Справочник по AngularJS ng-repeat API - Отслеживание

Другие вопросы по тегам