转发器中的重复项不允许有角度

时间:2013-10-10 07:16:37

标签: angularjs angularjs-directive

我正在尝试创建一个如下所示的表单,这是使用角度的ng-repeat指令,每当我创建一个新行时就会抱怨 “不允许在转发器中复制。”

enter image description here

虽然我理解这个问题的解决方案是放"track by $index"但是它会导致另一个问题,即在一行上单击删除会删除其他字段的值。所以我怀疑索引的跟踪对静态文本是好的,但不是输入形式。那么如何正确使用ng-repeat呢?

我的jsfiddle:demo.

编辑:我知道对象的json数组将解决我的问题(因为对象angular create $$ hashKey)并且已经为我的大多数其他模块实现了这个。但我实际上期待一些可以在不改变我的json数组字符串的情况下完成的修复。很抱歉不清楚。

我目前的代码:

HTML

<div class="row-fluid spacer10">
    <a ng-click="addAKA()" class="btn btn-primary spacer5 left30"><i class="icon-plus icon-white"></i> Add New Alias</a>
</div>
<div class="row-fluid spacer10"></div>
<div class="row-fluid spacer5" ng-repeat="item in aliasList track by $index">
    <input type="text" class="span6 left30" ng-model="item">
    <button class="btn btn-danger" ng-click="deleteAKA($index)">delete</button>
    <BR/>
</div>

的Javascript

$scope.addAKA = function ()
{
    if($scope.aliasList == null)
    {
        $scope.aliasList = [];
    }
    $scope.aliasList.push("");
    $scope.aliasjson = JSON.stringify($scope.aliasList);
}


$scope.deleteAKA = function (idx)
{
    var aka_to_delete = $scope.aliasList[idx];
    $scope.aliasList.splice(idx, 1);
    $scope.aliasjson = JSON.stringify($scope.aliasList);
}

3 个答案:

答案 0 :(得分:6)

我猜这是在列表中有多个空字符串时引起的。

如果是这种情况,则会导致它,因为JS中的任何两个空字符串都是等于的,并且Angular repeater不允许重复值(如消息中明确说明的那样)。这是一个有效的决定,因为他们必须将列表中的对象与其DOM树相关联,以最大限度地减少DOM操作。

解决方案是在模型中插入包含字符串的简单对象:

$scope.addAKA = function () {
    ...
    $scope.aliasList.push({value:""});
    ...
};

调整模板:

<input type="text" class="span6 left30" ng-model="item.value">

由于所有新对象都不同,因此应该解决您的问题。


查看实现过滤器的fiddle,将模型转换回字符串列表。

答案 1 :(得分:2)

当您输入新创建的input时,您的list保持不变。任何list更改的Angular都会更新视图(ng-repeat)并删除所有新存储的文本。因此,我们需要添加ng-change以更新list任何input更改

ng-change="change(i, $index)添加到您的商品中,它应该有效

<强> HTML

    <div ng-controller='ctrl'>
    <ol>
        <li ng-repeat='i in list track by $index'>
            <input type='text' ng-model='i' ng-change="change(i, $index)"></input>
            <button ng-click='deleteItem($index)'>Delete</button>

        </li>
    </ol>
    <button ng-click='addItem()'>Add</button>
    <div>ITEM: {{list | json}}</div>
</div>

<强>的Javascript

    angular.module("app", []).controller("ctrl", function ($scope) {
    $scope.list = ["one","two"];

    $scope.addItem = function () 
    {
        $scope.list.push("");
    };

    $scope.deleteItem = function (idx) 
    {
        var item_to_delete = $scope.list[idx];
        $scope.list.splice(idx, 1);
    };

    $scope.change = function (item, idx) 
    {
       $scope.list[idx] = item;
    };

});

DEMO

中查看固定演示

答案 2 :(得分:0)

是的,推送多个空字符串会导致ng-repeat抱怨。

此外,您还可以尝试:

  if ($scope.aliasList.indexOf(VALUE_TO_ADD) === -1) {
      ...
  }