AngularJS:ng在自定义指令中重复不更新

时间:2014-11-20 17:08:01

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

我创建了一个包含ng-repeat的自定义指令。如果我从指令触发模型更新,则ng-repeat在视图中发生其他情况之前不会显示数据更改。我确定数据已正确更新。这是代码:

控制器:

app.controller('myCTRL', ['$scope', function ($scope) {
    //the 'model':
    $scope.data=[];
    for (var i = 0; i < 9; i++)
        $scope.data.push({
            'val':i+1,
            'pos':i+1
        });

    $scope.directiveOptions = {
        changeData: function (from, to) {
            //here is the data update:
            var tmp= $scope.data[from].val;
            $scope.data[from].val =$scope.data[to].val;  
            $scope.data[to  ].val =tmp;
        }
    };

    $scope.revertData = function () {
        for (var i = 0; i < 9; i++)
            $scope.data[i].pos = $scope.data[i].pos * -1;
    };
}]);

查看:

<div ng-controller="myCTRL">
     <div id="container" ng-my-directive='directiveOptions'>
         <div ng-repeat="item in data | orderBy:'pos'" class="itemClass" >
             <div>
                 {{item.val}}
             </div>
         </div>
    </div>
    <div ng-click="revertData()">revert</div>
</div>

指令:

app.directive('ngMyDirective', function () {
    return {
        restrict: 'A',
        scope: { 
            directiveOptions: '=ngMyDirective' 
        },
        link: function (scope, elem, attr) {

            //...

            elem.on(
                'mouseup',
                function (e) {
                    // here I call the data change, but ng-repeat doesn't update
                    var from=2, to=3;
                    if (scope.directiveOptions.changeData){
                        scope.directiveOptions.changeData(from, to);
                    }
                }
            );
            //...
        }
    };
});

如果我点击revertData div,我可以看到更新的数据。 我必须在$apply()的末尾强制changeData或在ng-mouseover=""中添加空ng-repeat,但我无法相信这些是最好的方法所以,他们似乎只是诡计。

我错过了什么?

修改

正如@yarons所建议的,在jQLite事件中使用$ evalAsync,数据更改涉及视图更新。但我不确定这是最佳做法。我正在从指令嵌套的ng-repeat访问$ scope变量。该指令实现了影响模型的DOM操作。这是最好的方法吗?

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您的数据会在mouseup的事件侦听器回调中发生变化。 在这种情况下,您的数据会在Angular摘要循环之外更改,因此在角度视图中不会更改。 尝试使用

elem.on(
  'mouseup', function (e) {
     scope.$evalAsync(function() {
       var from=2, to=3;
       if (scope.directiveOptions.changeData){
         scope.directiveOptions.changeData(from, to);
       }
     });
   }
);