2015-08-25 15 views
9

Avere la seguente direttivaDue direttive condividono lo stesso controller

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

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

e questo in un modello:

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

Perché vedo il seguente output:

2 
2 

invece di

1 
2 

?

risposta

14

L'opzione controllerAs: 'foo' effettua le seguenti operazioni:

$scope.foo = new ctrl() 

tuo direttiva doesn' t specificare lo scope, ovvero la direttiva utilizza l'ambito dal suo genitore ($parentScope). Nel tuo caso, le due istanze direttiva utilizzano lo stesso ambito genitore. Così le due direttive:

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

lavoro come:

  1. <directive name="1" />: $parentScope.foo = new ctrl(). All'interno del controller: $parentScope.foo.name = 1.
  2. <directive name="2" />: $parentScope.foo = new ctrl(). (l'istanza nel passaggio 1 viene sovrascritta). All'interno del controller: $parentScope.foo.name = 2.

Quindi, infine, entrambe le direttive si riferiscono allo stesso name definito nella seconda istanza del controller.

Soluzione: utilizzare l'ambito isolato come @Michelem mentions.

+2

buona spiegazione del perché è necessario un ambito isolato, non solo che è necessario – charlietfl

3

si deve isolare il campo di applicazione:

JSFiddle

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

Guarda @Joy answer per la spiegazione

+0

Ma come posso utilizzare l'ambito isolato quando sto utilizzando la direttiva attributi nell'elemento 'input'? Ho ricevuto l'errore: https://docs.angularjs.org/error/$compile/multidir – robsonrosa

Problemi correlati