【问题标题】:duplicates in a repeater are not allowed angular转发器中的重复项不允许有角度
【发布时间】:2014-05-23 03:54:33
【问题描述】:

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

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

我的 jsfiddle :demo.

编辑:我知道对象的 json 数组将解决我的问题(因为对象角度创建 $$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);
}

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    我猜这是由于列表中有多个空字符串造成的。

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

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

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

    并调整您的模板:

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

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


    查看fiddle,其中实施了过滤器以将模型转换回字符串列表。

    【讨论】:

    • 实际上 2 个空字符串问题可以使用逐个索引来解决。但它会产生另一个问题,即按索引删除不再起作用。
    • 是的,在小提琴中(见编辑)我没有使用$index,而是我提到的对象方法。
    【解决方案2】:

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

    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

    中的固定演示

    【讨论】:

    • 感谢这个巧妙的技巧:“item in items track by $index”
    【解决方案3】:

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

    另外,你也可以试试:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      相关资源
      最近更新 更多