在表行中使用md-autocomplete和添加/删除命令

问题描述 投票:0回答:1

我有一个显示为表格的请求数组,我尝试在每一行中实现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;
    }

  }
})();
html angularjs angularjs-material md-autocomplete
1个回答
0
投票

删除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);
}
© www.soinside.com 2019 - 2024. All rights reserved.