Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS directives - best practices when using ngModel with jQuery widget

Here is my problem. For example, we have the following directive, which uses some jQuery widget behind the scenes :

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);
            });
        }
    };
}]);

So, if model's value changes, then the handler which is registered using $watch to listen for changes in model will be executed, and, consequently, widget's 'set_value' method will be executed too. This means that 'value_updated' event will be triggered.

My question is: what is the best practice to implement similar behavior in directives to avoid extra calls of DOM event handlers and watchers?

like image 940
oaleynik Avatar asked Mar 13 '13 18:03

oaleynik


1 Answers

Instead of scope.$watch(), I suggest implementing ctrl.$render(). $render should only be called if something inside Angular changes the model. Fiddle example.

This solves a problem you did not mention. Unfortunately, it does not solve the problem you did mention. In the fiddle, a blur event is bound, rather than some widget.on() event. Maybe that would work for you – i.e., only update the model on blur, rather than every keystroke (this assumes your widget is accepting keystrokes, however).

Maybe you could also ask the widget author to provide a "set" method that does not trigger an event. Then that could be used in the $render() method.

like image 125
Mark Rajcok Avatar answered Oct 11 '22 02:10

Mark Rajcok