2013-03-13 31 views
11

这是我的问题。例如,我们有以下指令,它在后台使用一些jQuery的插件:AngularJS指令 - 使用ngModel和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); 
      }); 
     } 
    }; 
}]); 

所以,如果模型的价值变化,那么这是使用$腕表监听模型改变注册的处理程序将被执行,因此,小部件的'set_value'方法也将被执行。这意味着'value_updated'事件将被触发。

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

回答

4

相反的scope.$watch(),我建议实施ctrl.$render()。只有在Angular内部改变模型时才应该调用$ render。 Fiddle example

这解决了你没有提到的一个问题。不幸的是,它不能解决你提到的问题。在小提琴中,绑定了一个blur事件,而不是一些widget.on()事件。也许这对你的工作–即,只有模糊更新模型,而不是每个击键(这假设你的小部件接受击键,但是)。

也许你也可以问widget作者提供不触发事件的“设置”方法。然后可以在$ render()方法中使用它。

+0

感谢马克,您的解决方案完美地解决了我的问题。但是,你能否告诉我们 - 何时适合使用观察者,何时执行$ render? – oaleynik 2013-03-14 08:02:19

+2

@oaleynik,$ render()应该在你想做某事时被实现,因为在Angular中改变了ng-model的值。 ng-model会自动为我们设置手表,如果它发现变化,则会调用$ render()。所以通常情况下,使用ng-model,你想实现$ render而不是使用你自己的$ watch。 – 2013-03-14 15:35:03