一尘不染

如何为自定义指令实现ng-change

angularjs

我有一个带有模板的指令

<div>
    <div ng-repeat="item in items" ng-click="updateModel(item)">
<div>

我的指令声明为:

return {
    templateUrl: '...',
    restrict: 'E',
    require: '^ngModel',
    scope: {
        items: '=',
        ngModel: '=',
        ngChange: '&'
    },
    link: function postLink(scope, element, attrs) 
    {
        scope.updateModel = function(item)
        {
             scope.ngModel = item;
             scope.ngChange();
        }
    }
}

我想ng-change在单击某个项目并且其值foo已经更改时调用。

也就是说,如果我的指令实现为:

<my-directive items=items ng-model="foo" ng-change="bar(foo)"></my-directive>

我希望bar在的值foo已更新时致电。

使用上面给出的代码,ngChange可以成功调用,但是将使用旧值foo而不是新的更新值来调用它。

解决该问题的一种方法是ngChange在超时值内部调用超时,以在将来某个时刻执行该超时foo。但是这种解决方案使我无法控制应该执行的顺序,并且我认为应该有一个更优雅的解决方案。

我也可以foo在父级作用域中使用观察程序,但是此解决方案并没有真正实现该ngChange方法,并且有人告诉我观察程序是内存消耗大的用户。

有没有一种方法可以使ngChange同步执行而没有超时或观察者?

示例:http//plnkr.co/edit/8H6QDO8OYiOyOx8efhyJ?p
= preview


阅读 305

收藏
2020-07-04

共1个答案

一尘不染

如果你需要ngModel,你可以叫$setViewValuengModelController,它隐评估ng- change。链接功能的第四个参数应该是ngModelCtrl。以下代码将对ng-change您的指令起作用。

link : function(scope, element, attrs, ngModelCtrl){
    scope.updateModel = function(item) {
        ngModelCtrl.$setViewValue(item);
    }
}

为了使您的解决方案起作用,请从myDirective的孤立范围中删除ngChange和ngModel。

这是一个小问题:http
://plnkr.co/edit/UefUzOo88MwOMkpgeX07?
p=
preview

2020-07-04