简体   繁体   中英

Angular - splice function always removes last element

I have an array of objects that I want to remove certain objects when a Delete key is clicked. However, it always removes the last item from the rows array, no matter how many rows I have created. Even if I explicitly put in a line like so, $scope.rows.splice(1,1) - it will still remove the last element, not the second.

JS

angular.module('app', ['ngAnimate', 'ui.bootstrap'])
  .directive('queryBuilder', function() {
    return {
      restrict: 'E',
      scope: {},
      controller: function($scope) {
        $scope.rows = [{}]

        $scope.$on('addRowRqst', function(evt) {
          // evt.stopPropagation()
          $scope.rows.push({})
        });
        $scope.$on('removeRowRqst', function(evt, args) {
          // evt.stopPropagation()
          //THIS IS WHERE THE REMOVE HAPPENS 
          $scope.rows.splice($scope.rows.indexOf(args),1);
        });        
      },
      templateUrl: 'queryBuilderTemplate.html',
    }
  }).directive('queryRow', function() {
    return {
      scope: {},
      restrict: 'EA',
      templateUrl: 'queryRowTemplate.html',
      controller: function($scope) {
        $scope.addRqst = function() {
          $scope.$emit('addRowRqst')
        };
        $scope.removeRqst = function(index) {
          $scope.$emit('removeRowRqst', index)
        };
      },
      link: function(scope, elem, attrs) {

      }
    }
  });

The relevant snippet of HTML

....
<button class="btn btn-default" ng-click="removeRqst($parent.row)" type="submit">Delete Row</button>
....

Plunker: http://plnkr.co/edit/rDkXpIgiOSoNvLNPsVbP

Test: Click on Add Row 3 times. Then click on Delete on second row. You will see that it actually removes the 3 row, not 2nd

Just to be clear with the answer @ZsoltGyöngyösi gave:

Every element with and id field needs ng-model="$parent.row.field"

Thus, the correct row will be deleted if you setup queryRowTemplate.hml this way:

queryRowTemplate.html

<div class="form-group col-md-3">
  <label for="selectedField">Select Field</label>
  <select id="selectedField" class="form-control" ng-model="$parent.row.field">
    <option>title</option>
    <option>application</option>
    <option>subject</option>
    <option>filetype</option>
  </select>
</div>
<div class="form-group col-md-3">
  <label for="logicalOperator">Logical Operator</label>
  <select id="logicalOperator" class="form-control" ng-model="$parent.row.logical">
    <option>equal to</option>
    <option>not equal to</option>
  </select>
</div>
<div class="form-group col-md-3">
  <label for="searchText">Search</label>
  <input id="searchText" class="form-control" type="text" placeholder="search..." ng-model="$parent.row.search" />
</div>
<div class="form-group col-md-3">
  <label for="operator">Operator (optional)</label>
  <select id="operator" class="form-control" ng-model="$parent.row.operator">
    <option value=""></option>
    <option>AND</option>
    <option>OR</option>
  </select>
</div>
<button class="btn btn-default" ng-click="addRqst()" type="submit">Add Row</button>
<button class="btn btn-default" ng-click="removeRqst($parent.row)" type="submit">Delete Row</button>
{{$parent.$index}}
<hr />

See Plunkr, here

The code is fine, the correct form is being deleted. The problem is that you are not binding your view to the queryRow directive, so it seems that the last one is being deleted. In reality, angular rebuilds your view based on the array, not knowing about the content of the templates. Hence unbound input fields simply retain the values, except for the last one.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM