Angular.js - updating parent scope from directive

angularjs, javascript

Solution

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

Problem

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.

Original source

Related problems