Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two directives are sharing the same controller

Having the following directive

function directive() {
    return {
        template: '{{foo.name}}',
        controller: ctrl,
        controllerAs: 'foo'
    }
}

function ctrl($attrs) {
    this.name = $attrs.name;
}

and this in a template:

<directive name="1" />
<directive name="2" />

Why am I seeing the following output:

2
2

instead of

1
2

?

like image 688
redhead Avatar asked Aug 25 '15 15:08

redhead


2 Answers

The option controllerAs: 'foo' does the following:

$scope.foo = new ctrl()

Your directive doesn't specify the scope, that means your directive uses the scope from its parent ($parentScope). In your case, the two directive instances use the same parent scope. So the two directives:

<directive name="1" />
<directive name="2" />

Work like:

  1. <directive name="1" />: $parentScope.foo = new ctrl(). Inside the controller: $parentScope.foo.name = 1.
  2. <directive name="2" />: $parentScope.foo = new ctrl(). (the instance in step 1 is overwritten). Inside the controller: $parentScope.foo.name = 2.

So finally both directives refer to the same name defined on the second controller instance.

Solution: use isolate scope as @Michelem mentions.

like image 125
Joy Avatar answered Oct 11 '22 09:10

Joy


You have to isolate the scope:

JSFiddle

function directive() {
    return {
        scope: {name: '='},
        template: '{{foo.name}}',
        controller: ctrl,
        controllerAs: 'foo'
    }
}

Look at @Joy answer for explanation

like image 39
michelem Avatar answered Oct 11 '22 09:10

michelem