2015-01-15 15 views
8

Il codice angolare placed on jsfiddle è per quanto riguarda una direttiva personalizzato, che utilizza $compile($element)($scope) e fa sì che l'azione ng clic per accadere due volte: Le mie domande sono :

  • Mi piacerebbe capire, perché l'azione ng-clic sta accadendo due volte?
  • Qual è lo scopo di chiamare $compile($element)($scope)?
  • cosa succede se non viene chiamato, in quali circostanze si dovrebbe chiamare ?

Ecco i dettagli e quello che ho raccolto finora:

Vorrei capire, perché è il ng-clic su Azione accadendo due volte? La seguente riga mostra la direttiva personalizzata "ciao" e ng-clic su un pulsante. La direttiva personalizzata chiama $compile($element)($scope) e questa è la linea che fa scattare l'azione due volte, ma non capisco come?

Test CLIC!

Ecco il codice - http://jsfiddle.net/4x4L3gtw/27/

<div ng-app='myApp' ng-controller='DirectiveTestController'> 
    <button hello ng-click="testClick()">Test CLICK!</button> 
</div> 

var myApp = angular.module('myApp', []); 
myApp.controller('DirectiveTestController', ['$scope', 

function ($scope) { 
    $scope.testClick = function() { 
     window.alert("hey"); 
     console.log("hey"); 
    } 
}]); 
myApp.directive('hello', function() { 
    return { 
     scope: true, 
     controller: ['$scope', '$element', '$compile', function ($scope, $element, $compile) { 
      $element.removeAttr('hello'); 
      //   $element.removeAttr('ng-click'); 
      $compile($element)($scope); 
     }] 

    }; 
}); 

Qual è lo scopo di chiamare $compile($element)($scope), cosa succede se non è chiamato e in quali circostanze dovrebbe essere chiamato?

(cliccare sul pulsante e si noterà che l'azione accade due volte)

L'intento della direttiva è quello di nascondere/disattivare sulla base di una logica. così in questa direttiva vedo $element.removeAttr("ng-hide"), ecc, e ogni volta il $element.removeAttr si chiama è seguito con un $compile($element)($scope), è lo scopo di riscrivere il DOM?

Ho esaminato il DOM e non vedo ng-clic definito più volte. Durante l'esame del DOM (firebug), ho esaminato $ element-> 0-> attributes-> ng-click (tra gli altri elementi).

Se rimuovo ng-clic utilizzando $element.removeAttr("ng-click") allora l'azione accade solo una volta. Oppure se rimuovo lo $compile($element)($scope) l'azione si verifica solo una volta.

risposta

0

penso che tali operazioni (con html) dovrebbero essere in collegamento (non nel controllore):

link: function (scope, element) { element.removeAttr('hello'); }

http://jsfiddle.net/4x4L3gtw/32/

+0

Rodion grazie, la prego di spiegare perché il metodo di collegamento al posto del controller – liontale

+0

buona spiegazione delle differenze tra controller e creare un collegamento si può trovare in altra domanda: http://stackoverflow.com/questions/15676614/directive-link-vs-compile-vs-controller. Non ne sono sicuro, ma a mio avviso il motivo principale, perché dovresti fare operazioni con DOM in link è perché il link richiama dopo la compilazione html. – Rodion

0

compilare - $ compileProvider - servizio nel modulo ng compila un Stringa HTML o DOM in un modello e produce una funzione modello, che può quindi essere utilizzata per collegare insieme l'ambito e il modello.

La compilazione è un processo di spostamento dell'albero DOM e di corrispondenza degli elementi DOM con le direttive.

+0

Grazie a DK, nella mia direttiva voglio solo rimuovere removettr in alcuni degli attributi, e il DOM viene aggiornato dopo aver chiamato removeAttr, quindi perché devo chiamare $ compilare? – liontale

3

Penso che il motivo principale per cui questo accade sia perché si sta utilizzando un evento click nell'elemento in cui si applica la direttiva, invece di definire questo evento direttamente nella direttiva. Pertanto si ottiene il clic dall'elemento del pulsante, ma anche il clic dal controller della direttiva.

Ciò che $ compiles fa una volta invocato contro markup genererà una funzione che è possibile utilizzare per associare il markup a un particolare ambito (ciò che Angular chiama una funzione di collegamento), ecco perché suggeriamo di utilizzare il link Rodion. In questo caso particolare, significa che stai utilizzando un evento direttamente nel pulsante dell'elemento, ma poi lo ricolleghi all'ambito della direttiva usando $ compile. Immagino sia per questo che ricevi il messaggio due volte.

Poiché non so se questo è chiaro, ho ottenuto le informazioni da questo link http://odetocode.com/blogs/scott/archive/2014/05/07/using-compile-in-angular.aspx dove è spiegato in modo migliore.

Qui anche un JSFiddle in cui è possibile vedere come funziona (estratto dall'articolo precedente).

app.directive("otcDynamic", function($compile){ 
    return { 
     link: function(scope, element){ 
      var template = "<button ng-click='doSomething()'>{{label}}</button>"; 
      var content = $compile(template)(scope); 
      element.append(content); 
     } 
    }; 
}); 

JSFiddle