两个指令共享同一个控制器

时间:2021-03-17 12:15:10

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

?

2 个解决方案

#1


14  

The option controllerAs: 'foo' does the following:

选项controllerAs:'foo'执行以下操作:

$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:

您的指令未指定范围,这意味着您的指令使用其父级($ parentScope)中的范围。在您的情况下,两个指令实例使用相同的父作用域。所以这两个指令:

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

Work like:

工作如下:

  1. <directive name="1" />: $parentScope.foo = new ctrl(). Inside the controller: $parentScope.foo.name = 1.
  2. :$ parentScope.foo = new ctrl()。在控制器内:$ parentScope.foo.name = 1。
  3. <directive name="2" />: $parentScope.foo = new ctrl(). (the instance in step 1 is overwritten). Inside the controller: $parentScope.foo.name = 2.
  4. :$ parentScope.foo = new ctrl()。 (第1步中的实例被覆盖)。在控制器内部:$ 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.

解决方案:使用隔离范围作为@Michelem提及。

#2


3  

You have to isolate the scope:

你必须隔离范围:

JSFiddle

的jsfiddle

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

Look at @Joy answer for explanation

看看@Joy答案的解释

#1


14  

The option controllerAs: 'foo' does the following:

选项controllerAs:'foo'执行以下操作:

$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:

您的指令未指定范围,这意味着您的指令使用其父级($ parentScope)中的范围。在您的情况下,两个指令实例使用相同的父作用域。所以这两个指令:

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

Work like:

工作如下:

  1. <directive name="1" />: $parentScope.foo = new ctrl(). Inside the controller: $parentScope.foo.name = 1.
  2. :$ parentScope.foo = new ctrl()。在控制器内:$ parentScope.foo.name = 1。
  3. <directive name="2" />: $parentScope.foo = new ctrl(). (the instance in step 1 is overwritten). Inside the controller: $parentScope.foo.name = 2.
  4. :$ parentScope.foo = new ctrl()。 (第1步中的实例被覆盖)。在控制器内部:$ 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.

解决方案:使用隔离范围作为@Michelem提及。

#2


3  

You have to isolate the scope:

你必须隔离范围:

JSFiddle

的jsfiddle

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

Look at @Joy answer for explanation

看看@Joy答案的解释