$ index指向角度ng-repeat轨道

时间:2015-04-08 11:16:33

标签: angularjs angularjs-ng-repeat angular-directive

我无法理解为什么如果我在ng-repeat中使用索引跟踪,在从数组中删除项目后,我会在指令范围内得到“错误”值。

正如您在下面的plunker中看到的,如果我删除索引跟踪的数组中的第一个Item,则指令范围中的值将不是初始值。

我希望在删除后有: 2 - b 3 - c

但是我明白了 2 - a 3 - b

如果我不按索引使用track,我会得到正确的值。

这是脚本

nsTests.controller('nsTestCtrl', ['$rootScope', '$scope', '$filter', '$timeout',
function ($rootScope, $scope, $filter, $timeout) {

    $scope.data = [
     {
         id: 1,
         name: 'a'
     },
     {
         id: 2,
         name: 'b'
     },
     {
         id: 3,
         name: 'c'
     },
    ];

    $scope.data2 = [
     {
         id: 1,
         name: 'a'
     },
     {
         id: 2,
         name: 'b'
     },
     {
         id: 3,
         name: 'c'
     },
    ];

    $scope.removeByIndex = function (index) {
        $scope.data.splice(index, 1);            
    }

    $scope.removeByItem = function (item) {
        var index = $scope.data2.indexOf(item);
        if (index !== -1) {
            $scope.data2.splice(index, 1);
        }
    }
}
]);


nsTests.directive('test', function ($compile) {
return {
    restrict: 'E',
    template: '{{value}}',
    scope: {
        data: '='
    },
    controller: function ($scope) {
        $scope.value = $scope.data.name;            
    }
};
});

这是一个带有问题的plunker

2 个答案:

答案 0 :(得分:1)

我认为我的plnkr和解释会帮助您更好地理解这些事情。

此问题不适用于track by $index

nsTests.directive('test', function ($compile) {
    return {
        restrict: 'E',
        template: '{{value}}',
        scope: {
            data: '='
        },
        controller: function ($scope) {
            $scope.value = $scope.data.name;            
        }
    };
});

您已为测试指令创建了隔离范围,并且您正在将数据变量的值分配给测试指令的$scope.value。 指令只编译一次所以一旦编译它就会绑定值,而不是父作用域变量的任何变化在这里没有影响,因为你创建了隔离范围并从父范围复制了值。

为了更好地理解指令,请查看本文

答案 1 :(得分:0)

  

使用索引跟踪,angular将重用节点

这实际上是问题所在;该指令未重新初始化,因为Angular似乎忽略了它的值参数并保留了索引中的原始数据。

E.g。

var arr = [
  { id: 0, status: "Pass" },
  { id: 1, status: "Fail" }
];

如果你重复这些数据,并在重复中有一个自定义指令,它会显示绿色圆点表示通过,红点表示失败。

示例:https://plnkr.co/edit/ytQ9p6YJOfrDubCGIc2N?p=preview



.pass {
  color: green;
}

.fail {
  color: red
}

.pass,
.fail {
  font-size: 24px;
}

<table>
  <th>ID</th>
  <th>Status</th>
  <tr>
    <td>1</td>
    <td class="pass">&squf;</td>
  </tr>
  <tr>
    <td>2</td>
    <td class="fail">&squf;</td>
  </tr>
</table>
&#13;
&#13;
&#13;

应用过滤器时,例如通过arr上的$ filter过滤出ID为1的对象

&#13;
&#13;
.pass {
  color: green;
}

.fail {
  color: red
}

.pass,
.fail {
  font-size: 24px;
}
&#13;
<table>
  <th>ID</th>
  <th>Status</th>
  <tr>
    <td>2</td>
    <td class="pass">&squf;</td>
  </tr>
</table>
&#13;
&#13;
&#13;

如您所见,1被滤除,但结果现在不正确。这是因为Angular有点懒惰而且没有重新初始化我们正在使用的指令,即使我们传入的数据现在不同。