AngularJS指令 - 将ngModel与jQuery小部件一起使用时的最佳实践

oal*_*nik 11 javascript angularjs angularjs-directive

这是我的问题.例如,我们有以下指令,它在后台使用一些jQuery小部件:

module.directive('myWidget', [function() {
    return {
        require: "ngModel",
        restrict: "A",
        replace: true,
        templateUrl: "templates/myWidget.html",
        link: function(scope, element, attrs, ctrl) {
            element.widget_name().on('value_updated', function(event) {
                scope.$apply(function() {
                    var newModelValue = event.some_value;
                    ctrl.$setViewValue(newModelValue);
                });
            });

            scope.$watch(attrs["ngModel"], function(value){
                element.widget_name('set_value', value);
            });
        }
    };
}]);
Run Code Online (Sandbox Code Playgroud)

因此,如果模型的值发生变化,那么将执行使用$ watch注册以侦听模型中的更改的处理程序,因此,widget的'set_value'方法也将被执行.这意味着将触发'value_updated'事件.

我的问题是:在指令中实现类似行为以避免额外调用DOM事件处理程序和观察者的最佳做法是什么?

Mar*_*cok 4

相反scope.$watch(),我建议实施ctrl.$render(). 仅当 Angular 内部的某些内容更改了模型时才应调用 $render。 小提琴的例子

这解决了您没有提到的问题。不幸的是,它并不能解决你提到的问题。在小提琴中,blur绑定了一个事件,而不是某个 widget.on() 事件。也许这对你有用——即,仅在模糊时更新模型,而不是每次击键(但这假设你的小部件正在接受击键)。

也许您还可以要求小部件作者提供一个不触发事件的“设置”方法。然后可以在 $render() 方法中使用它。

  • @oaleynik,只要你想做某事,就应该实现 $render() ,因为 ng-model 值在 Angular 内部发生了更改。ng-model 会自动为我们设置 watch,如果它注意到变化,就会调用 $render() 。所以通常情况下,使用 ng-model,您希望实现 $render 而不是使用您自己的 $watch。 (2认同)