2012-10-23 9 views
10

Ciao Ho questa direttiva tasto "confermabile", che sto lavorando su,angular.js: come passare ngclick dalla dom originale alla dom della direttiva?

il codice HTML che attiverà la direttiva 'confirmable'

 <span confirmable ng-click='users.splice($index,1)'></span> 

direttiva: (CoffeeScript)

angular.module('buttons',[]) 

    .directive 'confirmable',() -> 
    template: """ 
     <button class='btn btn-mini btn-danger'> 
     Destroy 
     </button> 
    """ 
    replace: yes 

Così il risultato finale mi piacerebbe vedere generata con questa direttiva è

 <button class='btn btn-mini btn-danger' ng-click='users.splice($index,1)'> 
     Destroy 
     </button> 

Finora ho preso a lavorare con una funzione di collegamento all'interno della direttiva

angular.module('buttons',[]) 

    .directive 'confirmable',() -> 
    template: """ 
     <button class='btn btn-mini btn-danger'> 
     Destroy 
     </button> 
    """ 
    replace: yes 
    link: (scope, el, attrs) ->    <---------- linking function 
     $(el).attr 'ng-click', attrs.ngClick 

Ma ho passato attraverso la documentazione direttiva di nuovo, e hanno trovato la proprietà ambito con i =, @, & operatori ma io sono davvero insicuro se sono ciò di cui ho bisogno. Poi c'è questa proprietà di transizione che ho ancora bisogno di capire, ma al momento non sembra essere utile neanche. Quindi, mentre la mia funzione di collegamento fa il trucco per ora, ma ho pensato che dovrei chiedere di vedere se l'angolare fornisce una soluzione più elegante.

Grazie!

risposta

6

Sembra a me come si vuole chiamare un metodo da un ambito genitore dall'interno direttiva ...

Ho messo insieme un Plunk here

(Scusate, mi piace JavaScript ... ecco qui)

Ecco il controller genitore.

app.controller('ParentCtrl', function($scope) { 
    $scope.fooCalled = 0; 
    $scope.foo = function() { 
     $scope.fooCalled++; 
    }; 
}); 

Allora il tuo mark up

<div ng-controller="ParentCtrl"> 
    Foo Called: {{fooCalled}}<br/> 
    <button ng-click="foo()">Call From Parent</button><br/> 
    <custom-control custom-click="foo()"></custom-control> 
</div> 

E la tua dichiarazione di direttiva:

app.directive('customControl', function(){ 
    return { 
    restrict: 'E', 
    scope: { 
     innerFoo: '&customClick' 
    }, 
    template: '<button ng-click="innerFoo()">Call From Control</button>' 
    }; 
}); 

Il bit nella dichiarazione scope nella definizione di direttiva è quello che lega la funzione di riferimento ambito padre alla tua l'ambito della direttiva in modo che possa essere richiamato al clic. Questo è ciò che lo & è per lì.

+1

posso vedere che è molto utile, è quello di passare funzioni intorno come questo. Solo curioso, però, puoi passare argomenti a foo(), quindi? e come verrà trasferito alla direttiva? –

+0

Sì, è possibile passare argomenti. Le cose generalmente "scendono" dalla direttiva al genitore, non viceversa. Se hai richiesto qualcosa da fare sulla direttiva prima di chiamare il riferimento alla funzione genitore, allora dovresti semplicemente racchiudere quella chiamata in un'altra funzione di ambito nella dichiarazione del controllore della direttiva. –

+1

Hmm. Non è consigliabile riutilizzare 'ng-click' dal momento che è così comunemente noto? Funziona nel tuo esempio, ma se usi l'opzione 'replace: true' per la tua direttiva, si rompe. Non ho idea del perché. = [ – Langdon

1

Lo stai facendo bene. I controller servono per condividere le funzionalità comuni tra le direttive; non ne hai bisogno qui. Anche in questo caso è così semplice che non hanno nemmeno bisogno di una funzione di collegamento:

http://jsfiddle.net/V7Kpb/12/

Copia della direttiva attributi sopra nella fase di link non fare nulla per quanto angolare è interessato. Avrai solo un pulsante con un attributo ng-click ma che è stato aggiunto dopo che Angular ha elaborato il DOM.

Nota anche, element poiché il secondo parametro della funzione di collegamento è già jQLite (e presumibilmente jQuery completo se si ha anche quello collegato.) Non c'è bisogno di jQualificarlo.

Inoltre, per quanto riguarda gli ambiti tensione (l'=, @ e & si parla). È una bella sintassi elegante, ma il grosso lato negativo è che qualsiasi altra direttiva sullo stesso elemento viene isolata anche dall'ambito. Quindi, se vuoi lavorare con ngModel che è una cosa comune da fare, non puoi usare un ambito isolato. In realtà anche in questo caso, se usi un oggetto isolato ng-click smetti di funzionare. Perché proverà a valutare l'espressione che contiene cose non esplicitamente dichiarate nella proprietà scope {}.

1

Se manipolare il DOM in fase di collegamento e si desidera aggiungere logica angolare al suo elemento (s) è necessario compilare l'elemento effettato (s). Lasciate angolare iniettare $compile e invocare dopo aver terminato l'elaborazione del DOM e ha aggiunto tuoi ng-* direttive.

function MyDirective($compile) 
 
{ 
 
    return { 
 
     
 
     restrict: "AE", 
 
     templateUrl: "/path", 
 
     link: (scope, element, attributes) => 
 
     { 
 
      // Add your directives 
 

 
      $compile(element.contents())(scope); 
 
     } 
 
    }; 
 
}

Problemi correlati