当使用$ index跟踪时,ng-repeat内的自定义指令不能正确更新绑定值

时间:2014-07-02 18:40:57

标签: javascript angularjs angularjs-directive angularjs-ng-repeat angularjs-filter

我正在实现一个为某些列应用格式的自定义网格。 单击“切换排序”链接时,第二列不会跟踪第一列。但是,删除“跟踪$ index”会修复它。起初我明白绑定原始数据是问题,但事实并非如此。

<div ng-app="testApp">
    <div ng-controller="MyCtrl">
        <h3>With Track By</h3>
        <div ng-repeat="row in (filteredRows=(rows | orderBy:sort.column:sort.descending)) track by $index">
            <span>{{ filteredRows[$index].s }}</span><fmt data-model="filteredRows[$index]"></fmt>
        </div>
        <br/>
        <a href="#" ng-click="sort.descending = !sort.descending">Toggle Sort</a>
    </div>
</div>

angular.module('testApp', [])
.controller('MyCtrl', function($scope) {
    $scope.rows = [ 
        { v: 1.2345, s: 'foo' },
        { v: 0.1, s: 'bar' }, 
        { v: -3.33333, s: 'baz' }, 
        { v: 10, s: 'rar' } 
    ];
    $scope.sort = { column: 'v', descending: false };
})
.directive('fmt', function() {
    return {
        restrict: 'AE',
        scope: {
            model: '='
        },
        template: '<span style="display:inline-block;width:100px;text-align:right;">{{ model.v }}</span>' +
            '<span style="display:inline-block;width:100px;text-align:right;">{{ fmtModel }}</span>',
        controller: function($scope) {
            $scope.fmtModel = $scope.model.v.toFixed(2);
        }
    };
})

这个小提琴演示的问题:http://jsfiddle.net/4Hs36/5/

这是一种似乎有效的解决方法:http://jsfiddle.net/4Hs36/6/。在这里,我将格式化的值直接附加到模型中,但我不确定这是否是一个好主意。

希望有人能够更多地了解“追踪$ index”会发生什么?

2 个答案:

答案 0 :(得分:1)

我对范围有些不太了解。我的印象是你可以将一个属性附加到$ scope,它会在绑定值改变时自动更新。

我使用此http://jsfiddle.net/4Hs36/7/

更新了原帖中的小提琴
controller: function($scope) {
  $scope.fmtModel = function() { 
    return $scope.model.v.toFixed(2);
  }
}

我想我可以添加$ watch并以这种方式修复:http://jsfiddle.net/4Hs36/8/

controller: function($scope) {
  $scope.$watch('model.v', function() {
    $scope.fmtModel = $scope.model.v.toFixed(2);
  });
}

答案 1 :(得分:0)

我遇到了和你一样的问题。 我在Github提出了一个问题,他们回答说这是性能考虑的预期行为。 您可以查看详细信息:

https://github.com/angular/angular.js/issues/15363#issuecomment-258401432