我有一个显示为表格的请求数组,我尝试在每一行中实现md-autocomplete
以选择项目。用户可以添加,编辑或删除行。我尝试使用行索引来对此进行跟踪,但是当我删除和添加新行时,它导致了一些错误。数据行相互混合,或者当我添加新行时它显示已删除的项目值。毕竟,我想正确地获取请求数组。
我在这里有codepen。
<div ng-controller="DemoCtrl as vm" layout="row" ng-app="MyApp">
<md-content class="md-padding">
<form name="requestForm">
<table>
<thead>
<tr>
<th><span>Item</span></th>
<th class="quantity"><span>Quantity</span></th>
<th class="actions">
<md-button class="md-primary" aria-label="Add row" ng-click="vm.addRow()">Add Row
</md-button>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="request in vm.requests track by $index">
<td class="item">
<md-autocomplete
md-input-name="itemKey[$index]"
md-no-cache="true"
md-selected-item="vm.selectedItems[$index]"
md-selected-item-change="vm.selectedItemChange($index, item)"
md-search-text="vm.searchTextItem[$index]"
md-items="item in vm.searchItem(vm.searchTextItem[$index])"
md-item-text="item.name"
md-floating-label= "*"
md-require-match=""
ng-disabled="false"
md-delay = "300"
md-no-asterisk= true
md-autoselect=false
input-aria-describedby="Item">
<md-item-template>
<span md-highlight-text="vm.searchTextItem[$index]">{{item.name}}</span>
</md-item-template>
<div ng-messages="requestForm.itemKey[$index].$error" ng-if="requestForm.itemKey[$index].$touched">
<div ng-message="required"></div>
<div ng-message="md-require-match"></div>
</div>
</md-autocomplete>
</td>
<td class="quantity">
<md-input-container>
<input ng-model="request.quantity" name="quantity" type="number" min="0.01"
required aria-label="quantity">
<div ng-messages="requestForm.quantity.$error" role="alert">
<div ng-message="required"></div>
<div ng-message="number"></div>
<div ng-message="min"></div>
</div>
</md-input-container>
</td>
<td class="actions">
<md-button class="md-accent" ng-click="vm.deleteRow($index)" aria-label="Delete">Delete
</md-button>
</td>
</tr>
</tbody>
</table>
</form>
</md-content>
<textarea spellcheck="false" cols=48 rows=24>{{vm.getRequests()}}</textarea>
<textarea spellcheck="false" cols=48 rows=24>{{vm.getSelectedItems()}}</textarea>
</div>
我的控制器js
(function () {
'use strict';
angular
.module('MyApp',['ngMaterial', 'ngMessages'])
.controller('DemoCtrl', DemoCtrl);
function DemoCtrl ($timeout, $q) {
var vm = this;
vm.selectedItemChange = selectedItemChange;
vm.searchItem = searchItem;
vm.addRow = addRow;
vm.deleteRow = deleteRow;
vm.getRequests = getRequests;
vm.getSelectedItems = getSelectedItems;
vm.items = [];
vm.requests = [];
vm.selectedItems = {};
for (var i=0; i<100; i++) {
vm.items.push({key: i, name: "item"+i});
}
addRow();
function getRequests() {
return JSON.stringify(vm.requests, undefined, 4);
}
function getSelectedItems() {
return JSON.stringify(vm.selectedItems, undefined, 4);
}
function addRow() {
vm.requests.push({
'itemKey': '',
'quantity': 0
});
}
function deleteRow(index) {
vm.requests.splice(index, 1);
delete vm.selectedItems[index];
}
function createFilterFor(query) {
var lowercaseQuery = query.toLowerCase();
return function filterFn(rec) {
return (rec.name.toLowerCase().indexOf(lowercaseQuery) > -1);
};
}
function searchItem(query) {
var results = query ? vm.items.filter(createFilterFor(query)) : vm.items;
return results;
}
function selectedItemChange(index, item) {
if (!item) {return;}
vm.requests[index].itemKey = item.key;
}
}
})();
删除track by $index
:
<tbody>
̶<̶t̶r̶ ̶n̶g̶-̶r̶e̶p̶e̶a̶t̶=̶"̶r̶e̶q̶u̶e̶s̶t̶ ̶i̶n̶ ̶v̶m̶.̶r̶e̶q̶u̶e̶s̶t̶s̶ ̶t̶r̶a̶c̶k̶ ̶b̶y̶ ̶$̶i̶n̶d̶e̶x̶"̶>̶
<tr ng-repeat="request in vm.requests">
</tr>
</tbody>
[将ng-repeat
与数组对象一起使用时,track by $index
不是必需的,实际上会引起问题。
有关更多信息,请参阅
[selectedItemChange()和deleteRow()可能有问题
制作vm.selectedItems
数组并进行拼接以删除条目:
vm.deleteRow = deleteRow;
̶v̶m̶.̶s̶e̶l̶e̶c̶t̶e̶d̶I̶t̶e̶m̶s̶ ̶=̶ ̶{̶}̶;̶
vm.selectedItems = [];
function deleteRow(index) {
vm.requests.splice(index, 1);
̶d̶e̶l̶e̶t̶e̶ ̶v̶m̶.̶s̶e̶l̶e̶c̶t̶e̶d̶I̶t̶e̶m̶s̶[̶i̶n̶d̶e̶x̶]̶;̶
vm.selectedItems.splice(index,1);
}