2013-05-15 3 views
25

C'è un modo per passare variabili utilizzando attributi a una direttiva senza creare un nuovo ambito?Passare la variabile al modello direttiva senza creare un nuovo ambito

HTML

<div ng-click='back()' button='go back'></div> 

JS

.directive('button', function() { 
    return { 
     scope: { 
      button: '@' 
     }, 
     template: "<div><div another-directive></div>{{button}}</div>", 
     replace: true 
    } 
}) 

Il problema è che il ng-click='back()' ora si riferisce al campo di applicazione della direttiva. Posso ancora fare ng-click='$parent.back()' ma non è quello che voglio.

+0

si dovrebbe usare & attr per chiamare le funzioni genitore passate come attributo http://stackoverflow.com/questions/15991137/calling-method-of-parent-controller-from-a-directive-in-angularjs/15991525 –

+0

I vorrei avere un modo generico. Non 'scope: {back: '&'}' se è quello che intendi? Per essere in grado di fare: '

' per un altro esempio. –

risposta

32

Per impostazione predefinita, le direttive non creano un nuovo ambito. Se si vuole fare che esplicito, aggiungere scope: false alla direttiva:

<div ng-click='back()' button='go back!'></div> 
angular.module('myApp').directive("button", function() { 
    return { 
     scope: false, // this is the default, so you could remove this line 
     template: "<div><div another-directive></div>{{button}}</div>", 
     replace: true, 
     link: function (scope, element, attrs) { 
      scope.button = attrs.button; 
     } 
    }; 
}); 

fiddle

Dal momento che una nuova proprietà, button, viene creato sulla portata, si dovrebbe normalmente creare un nuovo ambito figlio usando scope: true come @ ardentum-c ha nella sua risposta. Il nuovo ambito sarà prototypially inherit dall'ambito principale, motivo per cui non è necessario inserire $parent.back() nel codice HTML.

Un altro bocconcino da ricordare: anche se stiamo usando replace: true, fare clic sull'elemento chiama ancora back(). Funziona perché "il processo di sostituzione migra tutti gli attributi/classi dal vecchio elemento a quello nuovo". - directive doc
Quindi ng-click='back()' button='go back!' vengono migrati al primo div nel modello della direttiva.

+0

Hai ragione, ma ho bisogno dell'ambito isolato per avere più pulsanti con nomi diversi. Domanda formulata male, credo. http://jsfiddle.net/gHjU4/2/ –

+0

OK ora mi sento stupido, come hai detto, 'scope: true' e nessuna compilazione necessaria. Ho cambiato la risposta accettata. –

2

Immagino che dovresti usare la funzione compilare in questo caso.

angular.module('myApp').directive("button", function() { 
    return { 
     template: "<div><div another-directive></div>{{button}}</div>", 
     replace: true, 
     scope: true, 
     compile: function (tElement, tAttrs) { 
      // this is link function 
      return function (scope) { 
       scope.button = tAttrs.button; 
      };    
     } 
    }; 
}); 

Ecco jsfiddle example.

+0

Non ho mai usato la compilazione prima ma l'ho visto nei documenti, dovrebbe leggerlo. Grazie ! –

+1

'scope: true' crea un nuovo ambito. Mentre penso che questo sia il modo corretto per farlo, l'OP non ha chiesto nuovi obiettivi. Inoltre, non è necessaria una funzione di compilazione, solo una funzione di collegamento. Vedi la mia risposta per maggiori informazioni. –