3

I'm trying to update a dict of values in a parent scope from a directive. The dict parent is updated through a function (explained here) so i dont really understand why when i print values i see them but when binding with a pre tag it's not changing. Plus, why is field.error not showing in the directive template ?

I set up a simplified exmaple of my problem in this jsbin

Angular newbi, and quite a frustrated one... Thanks.

Community
  • 1
  • 1
haki
  • 9,389
  • 15
  • 62
  • 110

1 Answers1

5

You are missing a scope.$apply when you handle the JS events in your directive.

The event handling happens in pure JS, outside the angular context and when you invoke the function on the parent scope, you are invoking it as you would invoke a function on any other plain JS object. Keeping plain JS objects instead of creating their own object hierarchies where they could intercept function calls is a design choice which Angular made different from, say, ember.

The value does change on the scope, it is just that Angular is not aware of it. The next time a $digest loop is triggered by anything (say a different button click with an ng-click), the change would show up. What we can do, however, is to make sure that the $digest loop is triggered by explicitly calling scope.$apply().

The fix is this:

element.bind("blur change keyup", function() { 
  // This will tell Angular to rerun the $digest loop
  // as we are changing some variables which Angular
  // should be informed about.
  scope.$apply(function () {  
    var val = element.find("input").val();
    var oldval = scope.values[scope.field.name];
    if (oldval !== val && isValid(val))
      scope.set_value(scope.field.name,val);
    //else
    //  scope.set_value(scope.field.name,undefined);
  });
});

Working demo: http://jsbin.com/inoKOVU/1/edit

musically_ut
  • 34,028
  • 8
  • 94
  • 106
  • Why is that ? i'm using a function to update the parent scope so ... from what i red it's using references to the parent so, where exactly is this code "running" without using apply ? – haki Nov 29 '13 at 09:10
  • Thanks for the answer @musically_ut. Can I set up two way binding with the parent dict using this method ? or i have to define an attribute and bind it to the directives scope with `"="` ? – haki Nov 29 '13 at 09:23
  • You can use an attribute on the directive and `$watch` the value inherited from the parent scope. – musically_ut Nov 29 '13 at 11:41