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

AngularJS : ngRepeat in custom directive not updating

本文关键字:更新 指令 ng 自定义 AngularJS      更新时间:2023-09-26

我创建了一个包含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);
                    }
                }
            );
            //...
        }
    };
});

如果我单击revertDatadiv,我可以看到更新的数据。我必须在changeData结束时强制$apply()或在ng-repeat中添加一个空ng-mouseover="",但我不敢相信这些是最好的方法,它们似乎只是技巧。

我错过了什么?

编辑

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

如果我

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

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