使用FormController从ng-repeat中删除元素

时间:2016-12-15 17:11:40

标签: javascript angularjs

ng-repeat内的表单输入存在很大问题。 我需要输入数组并且具有可变大小:用户可以添加和删除此表单的部分。

ng-formng-repeat - 我需要访问每个数组元素的$dirty值。 一切都有效,除了一件事 - 删除元素不会影响FormControllers。当我删除部分数组 在模型中,ng-repeat正确地从视图中删除了一个元素,但是ng-form 没有更新它的位置。

plunker

删除前:

$index = 0, formRepeated.$dirty == true,  model.value == 1

$index = 1, formRepeated.$dirty == false, model.value == 2

我从$scope.model删除了元素0。现在我有:

$index = 0, FormController $dirty == true, value == 2

附加的FormController不会更新其位置 - 保留$dirty, $touched, $erro等的值

我想我尝试了一切,但我被卡住了。任何想法如何处理这个问题?任何建议赞赏

HTML:

<div ng-controller="MyController">
  <form name="form">

    <div ng-repeat="modelPart in model track by $index">
      <div ng-form="formRepeated">
        <input type="text" ng-model="modelPart.value" name="form_{{$index}}_value">
        <button ng-click="$parent.removeFormRepeated($index)">
          Remove
        </button>
        <div>Is dirty: {{ formRepeated.$dirty }}</div>
      </div>
    </div>
    <button ng-click="addNew()">add new</button>

  </form>
</div>

JS:

var app = angular.module('app', []);

app.controller('MyController', function MyController($scope) {

  $scope.model = [{value: 1}, {value: 2}];

  $scope.addNew = function() {
    $scope.model.push({});
  }

  $scope.removeFormRepeated = function(index) {
    $scope.model.splice(index, 1);
  };
});

2 个答案:

答案 0 :(得分:0)

如果您在$index中使用ng-repeat,请小心跟踪它的值。一旦查看此link(也提供了plunker),您就可以了解由$index引起问题的主要原因。当项目被删除时,$ index值行为不端。

答案 1 :(得分:0)

我遇到了同样的问题,解决方案最终变得非常简单。 @SaiUnique提到的问题是$index

如果您的重复元素具有唯一的属性,请使用该元素,即track by element.uniqueProperty。否则,只需完全删除track by,然后只使用Angular生成的$$hashKey。这将保留您的嵌套表单。请参阅下面的示例。 (请注意,我使用的是ControllerAs语法和Angular v1.5.8)。

HTML:

<div ng-controller="Controller as ctrl">
    <div ng-repeat="repeatedElement in ctrl.array">
        <div ng-form="formRepeated">
            <input type="text" ng-model="repeatedElement.value" name="description">
            <button ng-click="ctrl.removeFormRepeated(repeatedElement)">Remove</button>
        </div>
    </div>
</div>

控制器内部:

var me = this;
me.removeFormRepeated = function(elementToDelete){
    //traverse the array and remove the element
    for(var i = 0; i < me.array.length; i++){
        //use Angular's $$hashKey as identifier
        if(me.array[i].$$hashKey === elementToDelete.$$hashKey){
            me.array.splice(i, 1);
        }
    }
}

出于我所知的原因,使用track by $index时,您可以从ng-repeat数组中删除正确的元素,但相应的FormController处理不当。使用$$hashkey或唯一属性而非$index似乎可以解决此问题。

我知道这个问题已经有了答案,但我只想详细说明,因为我花了很多时间自己处理这个问题!