Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

$compile throws error inconsistently if isolated-scope directive's priority is set/unset #4402

Closed
buunguyen opened this issue Oct 14, 2013 · 2 comments

Comments

@buunguyen
Copy link
Contributor

This bit me today. Assume having this directive:

app.directive('dir', function() {
  return {
    priority: 1, 
    scope: {},
    link: function() {}
  }
});

And controller:

<body ng-controller="MainCtrl" dir>
  <p>Hello {{name}}!</p>
</body>

The app will fail with:

Error: [$compile:multidir] Multiple directives [dir, ngController] asking for isolated scope on: <body ng-controller="MainCtrl" dir="" class="ng-isolate-scope ng-scope">

However, removing priority in the directive or set it to 0, the error disappears. Plunker is here: http://plnkr.co/edit/nElgQQklbiLlD9vuvRov?p=preview.

This is caused by this line: https://github.com/angular/angular.js/blob/master/src/ng/compile.js#L802

Is this intentional or a bug? If it's intentional, shouldn't it fail regardless of directives' priority? I can submit a PR if this is a bug.

@petebacondarwin
Copy link
Contributor

This does seem like a bug since either we block all cases where two or more directives request a new scope or new scopes can live beside a single isolated scope.

@buunguyen
Copy link
Contributor Author

I looked at 1.0.8 and noticed the same issue. The following is the behavior:

  • If multiple directives in an element ask for new scope (i.e. scope: true), only one scope is created and shared by all
  • If multiple directives in an element ask for new isolated scope => error
  • If one directive asks for isolated scope and others ask for new scope: this is the when the inconsistency happens:
    • If the isolated-scope-asking directive is applied before all new-scope-asking directives: error
    • If the isolated-scope-asking directive is applied after all new-scope-asking directives: all share the isolated scope, no error

The first 2 items should be fine, I think developers wouldn't be surprised when learning about them. For the third item, $compile should pick one path or another regardless of directive declaration order and priority.

Among the 2 choices, I think the error makes more sense. This is because when a directive asks for a new (but not isolated) scope, it might need to access properties of the parent scope. Using the isolated scope will break that directive. So it's better to fail fast.

What do you think?

buunguyen added a commit to buunguyen/angular.js that referenced this issue Oct 15, 2013
… applied before isolated-scope directive

Given dirA, which requests new scope, and dirB, which requests new & isolated scope. If dirA is applied *after* dirB, $compile reports an error ('Multiple directives [dirB, dirA] asking for new/isolated scope'), which is expected. However, if dirA is applied *before* dirB, e.g. because dirA has high priority, then no error is thrown. This is the inconsistency. Plus, dirA ends up sharing the isolated scope created for dirB, which may break dirA because it might need to access to parent scope's members. This fix addresses this situation by throwing error regardless of order of directive application.

Closes angular#4402
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.