Angular数组对象,按索引删除时总是删除最后一个元素。

3

我有一些类似这样的控制器:

app.controller("zipController", function($scope, $http, $rootScope, $timeout) {
  $scope.zipCodes = [];
  $scope.addZipCode = function() {
    $scope.zipCodes.push({code: '', distance: '25mi'});
  }
  $scope.removeZipCode = function(index) {
    console.log(index, 'index removing');
    $scope.zipCodes.splice(index, 1);
  }
});

app.controller("zipCodeController", function($scope, $http, $rootScope, $timeout) {

});

这里是HTML:
<label ng-click="addZipCodes=!addZipCodes; addZipCode();"><i class="fa fa-map-marker" aria-hidden="true"></i> Target Zip Codes <small>(Cities)</small></label>
<span ng-if="addZipCodes" style="white-space: normal;">
    <span ng-repeat="code in zipCodes track by $index" class="zipCodeInput" ng-controller="zipCodeController">
        <span class="zipCodeText">
            <input type="text" placeholder="Zip Code" ng-model="zipCode" class="zipCode">
        </span>
        <span class="zipCodeSelect">
            <select ng-model="zipCodeDistance" ng-value="code.distance" class="zipCodeDistance">
                <option value="25mi">25 miles</option>
                <option value="50mi">50 miles</option>
                <option value="100mi">100 miles</option>
            </select>
        </span>
        <span class="zipCodeRemove">
            {{$index}}
            <a ng-click="removeZipCode($index)">x</a>
        </span>
    </span>
    <label ng-click="addZipCode();" class="addZipCode"><i class="fa fa-plus-square" aria-hidden="true"></i> Add</label>
</span>

当我调用removeZipCode($index)函数时,它具有正确的索引,但它总是从数组中删除最后一个$scope.zipCodes,而不是正确的邮政编码索引。
有什么想法为什么会这样吗?

请问您能否创建一个可工作的代码片段/JSFiddle来重现这个问题吗? - Weedoze
在控制台日志行中返回了正确的索引吗? - epascarello
@epascarello 是的,它返回了正确的索引。 - Jordash
2
这是由于使用了 track by $index 引起的。 - devqon
@devqon,正确的做法是什么? - Jordash
有没有可能在 JSFiddle 里重现一下?我已经创建好了一个:https://jsfiddle.net/2yt04ztr/4/ - Giovani Vercauteren
3个回答

1
移除 "track by $index"。它将会正常工作。

我创建了一个模拟上述结构的fiddle,但它无法使用track by $index。你如何解释这个问题?(https://jsfiddle.net/2yt04ztr/4/) - Giovani Vercauteren

1
你可以使用这个:

ng-repeat="(index,value) in array"


0

ng-repeat 内的 ng-model 指令违反了规则:在你的 ng-model 中始终要有一个点 "."

<span ng-if="addZipCodes" style="white-space: normal;">
    <span ng-repeat="item in zipCodes track by $index" class="zipCodeInput" ng-controller="zipCodeController">
        <span class="zipCodeText">
            <!-- REMOVE 
            <input type="text" placeholder="Zip Code" ng-model="zipCode" class="zipCode">
            -->
            <!-- always have a dot in your ng-model -->
            <input type="text" placeholder="Zip Code" ng-model="item.code" class="zipCode">
        </span>
        <span class="zipCodeSelect">
            <!-- REMOVE
            <select ng-model="zipCodeDistance" ng-value="code.distance" class="zipCodeDistance">
            -->
            <!-- always have a dot in your ng-model -->
            <select ng-model="item.distance" ng-value="item.distance" class="zipCodeDistance">
                <option value="25mi">25 miles</option>
                <option value="50mi">50 miles</option>
                <option value="100mi">100 miles</option>
            </select>
        </span>
        <span class="zipCodeRemove">
            {{$index}}
            <a ng-click="removeZipCode($index)">x</a>
        </span>
    </span>
    <label ng-click="addZipCode();" class="addZipCode"><i class="fa fa-plus-square" aria-hidden="true"></i> Add</label>
</span>

因为 ng-repeat 指令为每个项目创建一个子作用域,所以当 ng-model 指令省略掉点号 . 时,模型会修改子作用域中的项而不是父作用域。
欲知详情请参见 AngularJS Wiki - The Nuances of Scope Prototypal Inheritance在 JSFiddle 上查看 DEMO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接