angularJS element.on callback and scope.$apply

All we need is an easy explanation of the problem, so here it is.

In this example, I have an input with an attached directive. The directive is meant to display messages next to the input. There’s another input and a button to add messages.
Once some messages are displayed, focusing on the input with the attached directive should clear the messages.
http://jsfiddle.net/viro/WBqxf/

So I have a directive with an isolated model, and I’m trying to update the model when the element which has the directive goes into focus.
It seems like I have to wrap event callbacks in scope.$apply if I want to update the model:

element.on('focus',function(){
    scope.$apply(function(){
        console.log("focus !");
        scope.tstMsg=[];
    })
});

I suppose I have to wrap it in $apply because I’m using jqlite event callbacks and I guess they run “outside” angularJS, but I didn’t find it clearly stated in the docs.

Am I doing it right or is it a hack ?

Is there a better way to do it ?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Whenever you are using a thrid party library and perform changes you need to let Angular know by calling $apply().

As @charlietfl mentioned ng-focus is even easier:

Controler

$scope.focus = function() {
    // Do something
}

HTML

<input ng-model="inp" tst-msg="message" ng-focus="focus()" />

See jsFiddle

Method 2

scope.$apply will cause a $digest to be run so any watchers on the scope will check for changes and fire where appropriate. Since as you say you’re just binding to an event (on just does addEventListener/attachEvent as appropriate) doing the scope.$apply in this context is valid.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply