4

Well, since 'improve this doc' button on AngularJS documentation site doesn't work and discussion is now closed, I'd like to ask a question about 'isolated scope pitfall' paragraph of ngModelController.

<div ng-app="badIsolatedDirective">
  <input ng-model="someModel"/>
  <div isolate ng-model="someModel"></div>
  <div isolate ng-model="$parent.someModel"></div>
</div>

angular.module('badIsolatedDirective', [])
  .directive('isolate', function() {
    return {
      require: 'ngModel',
      scope: { },
      template: '<input ng-model="innerModel">',
      link: function(scope, element, attrs, ngModel) {
        scope.$watch('innerModel', function(value) {
          console.log(value);
          ngModel.$setViewValue(value);
        });
      }
    };
});

I expected to see the third input affecting first one (cause we just isolated second input's scope and have no reference to 'someModel' scope value), btw behavior of this example is just stunning: second input affects first, third doesn't affect anything. So the question is: am I loosing the concept or just don't understand it, or there are mistakes (maybe, not mistakes, but just no connection to the topic) in the example code (well, I changed it on Plunkr to make it work as I expected).

KayakDave
  • 24,636
  • 3
  • 65
  • 68
starbeast
  • 103
  • 3
  • 8
  • I think there is definitively something wrong with the sample code presented and explanations provided (on angularjs site) since we can read : `You'll notice that the first div is not updating the input. However the second div can update the input properly` but what we can see when running the sample is the exact opposite of this sentence. – ben75 Dec 02 '13 at 09:46

1 Answers1

5

In 1.2.0 timely-delivery there was a major change (here) to how multiple isolate scope directives on the same element work. This change apparently hasn't been reflected in their documentation.

Prior to 1.2.0 all directives on an element shared an isolate scope if any of the directives requested an isolate scope. Therefore in the above example the ngModel directive shared the isolate directive's scope. Which is why we had to reference the parent scope like this- ng-model="$parent.someModel"

That is no longer true in 1.2.0.

In 1.2.0 and beyond the ngModel directive no longer shares scope with isolate. ngModel is now on the parent scope of the isolate directive. Thus we now need ng-model="someModel" instead of ng-model="$parent.someModel"

Here's their description of the change (keeping in mind as you read this that ngModel is a directive):

Make isolate scope truly isolate Fixes issue with isolate scope leaking all over the place into other directives on the same element.

Isolate scope is now available only to the isolate directive that requested it and its template.

A non-isolate directive should not get the isolate scope of an isolate directive on the same element,instead they will receive the original scope (which is the parent scope of the newly created isolate scope).

BREAKING CHANGE: Directives without isolate scope do not get the isolate scope from an isolate directive on the same element. If your code depends on this behavior (non-isolate directive needs to access state from within the isolate scope), change the isolate directive to use scope locals to pass these explicitly.

Before

<input ng-model="$parent.value" ng-isolate>

.directive('ngIsolate', function() {   return {
    scope: {},
    template: '{{value}}'   }; });

After

<input ng-model="value" ng-isolate>

.directive('ngIsolate', function() {   return {
    scope: {value: '=ngModel'},
    template: '{{value}}   }; });

Here's a version running 1.2.0-rc3 (the last version before this change) which operates like their documentation describes: http://jsfiddle.net/5mKU3/

And immediately after, 1.2.0 stable, we no longer need, or want, the reference to '$parent': http://jsfiddle.net/5mKU3/1/

KayakDave
  • 24,636
  • 3
  • 65
  • 68
  • 1
    Good explanation, thx. Sad to recognize some docs don't correlate with the current version of the library. – starbeast Dec 03 '13 at 08:33