【问题标题】:Angular - splice function always removes last elementAngular - 拼接功能总是删除最后一个元素
【发布时间】:2016-01-07 00:31:14
【问题描述】:

我有一个对象数组,我想在单击 Delete 键时删除某些对象。但是,无论我创建了多少行,它总是从行数组中删除最后一项。即使我像这样明确地放入一行 $scope.rows.splice(1,1) - 它仍然会删除最后一个元素,而不是第二个。

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) {

      }
    }
  });

HTML的相关sn-p

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

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

测试:点击 Add Row 3 次。然后点击第二行的删除。您会看到它实际上删除了第 3 行,而不是第 2 行

【问题讨论】:

  • 您的 plunker 似乎工作正常。你如何检查哪个项目被删除?请注意,您没有将输入绑定到对象。
  • 见我上面的测试评论。问题不在于消除。问题是删除正确的
  • Plunker 更清楚:plnkr.co/edit/IZN3XJMpJMyhrw1sEgOk 它工作正常。
  • 总是删除最后
  • 对,我不希望它总是删除最后一行。我希望它删除我单击删除按钮的特定行

标签: javascript angularjs angularjs-directive


【解决方案1】:

为了明确@ZsoltGyöngyösi 给出的答案:

每个带有 id 字段的元素都需要 ng-model="$parent.row.field"

因此,如果您以这种方式设置queryRowTemplate.hml,则会删除正确的行:

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

【讨论】:

    【解决方案2】:

    代码没问题,正在删除正确的表单。问题是您没有将视图绑定到 queryRow 指令,因此似乎最后一个被删除了。实际上,角度基于数组重建您的视图,而不知道模板的内容。因此,未绑定的输入字段仅保留值,最后一个除外。

    【讨论】:

    • 有趣,我不太确定我是否理解未绑定字段中保留其值的部分。例如,当我没有将视图绑定到模型时,如果我在文本输入中放了一些东西,它仍然保留在那里。所以你是说如果我有 3 行,第二行有文本“abc”-Angular 会重绘它并将“abc”放在第二行?
    • 查看这个 plunkr:plnkr.co/edit/QrXMMU58IV4rJSG0T0n7?p=preview 验证是否删除了正确的表单,但是输入字段在不应该保留值时保留了值。
    • 现在看到这个plnkr.co/edit/dSaePFJzXnF0kl2cTsMA?p=preview工作正常
    • 出现问题的原因是,您看到的内容是从父控制器呈现的,在您的 queryBuilder 中定义。所有子视图都基于数组迭代进行渲染。每当您对数组进行更改时,angular 都会简单地通过数组重复并删除/插入缺少的任何内容。由于子指令和父指令之间没有对象引用依赖关系,因此最后一项被删除。希望这能消除混乱:)
    • 顺便说一句,我的回答应该被接受,因为它解释了问题发生的原因,而不是简单地显示了神奇的修复方法:)
    猜你喜欢
    • 2021-07-14
    • 1970-01-01
    • 2019-08-03
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2012-02-25
    • 1970-01-01
    • 2023-01-23
    相关资源
    最近更新 更多