2015-01-15 8 views
8

Kod kanciasty placed on jsfiddle dotyczy dyrektywy niestandardowej, która używa $compile($element)($scope) i powoduje, że akcja ng-click zdarza się dwa razy: Moje pytania są :

  • Chciałbym zrozumieć, dlaczego akcja ng-click zdarza się dwukrotnie: ?
  • Jaki jest cel dzwonienia pod numer $compile($element)($scope)?
  • co się stanie, jeśli nie zostanie wywołany, w jakich okolicznościach należy go wywołać?

Oto szczegóły i co mam zebrane do tej pory:

Chciałbym zrozumieć, dlaczego jest ng-click akcja dzieje się dwa razy? W poniższym wierszu jest wyświetlana niestandardowa dyrektywa "cześć" i ng-kliknięcie przycisku. Dyrektywa niestandardowa wywołuje $compile($element)($scope) i jest to linia, która powoduje, że akcja jest uruchamiana dwukrotnie, ale nie rozumiem w jaki sposób?

Test KLIK!

Oto kod - 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); 
     }] 

    }; 
}); 

Jaki jest cel wywołanie $compile($element)($scope), co się dzieje, jeśli nie jest on nazywany iw jakich okolicznościach należy ją nazwać?

(kliknij na przycisku i można zauważyć, że akcja dzieje się dwa razy)

Intencją dyrektywy jest, aby ukryć/wyłączyć na podstawie pewnej logiki. tak w tej dyrektywie widzę $element.removeAttr("ng-hide"), itd. I za każdym razem, gdy wywoływana jest nazwa $element.removeAttr, a następnie $compile($element)($scope), czy celem jest ponowne napisanie DOM?

Sprawdziłem DOM i nie widzę wielokrotnego kliknięcia ng-click. Podczas badania DOM (firebug) przyjrzałem się elementom $-> 0-> attributes-> ng-click (między innymi elementami).

Jeśli usunę ng-click za pomocą $element.removeAttr("ng-click"), akcja dzieje się tylko raz. Lub jeśli usunę ten $compile($element)($scope), akcja dzieje się tylko raz.

Odpowiedz

0

myślę takie operacje (z HTML) powinny być w linku (nie w kontrolerze):

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

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

+0

Rodion dzięki, czy mógłbyś wyjaśnić, dlaczego metoda Link zamiast kontroler – liontale

+0

dobre wyjaśnienie różnic pomiędzy kontrolerem i połączyć można znaleźć w innym pytaniu: http://stackoverflow.com/questions/15676614/directive-link-vs-compile-vs-controller. Nie jestem pewien, ale moim zdaniem głównym powodem, dla którego powinieneś wykonywać operacje z DOM w linku jest to, że link wywołuje po kompilacji html. – Rodion

0

skompilować - $ compileProvider - usługa w module ng kompiluje Ciąg HTML lub DOM do szablonu i tworzy funkcję szablonu, która może być następnie używana do łączenia zakresu i szablonu razem.

Kompilacja to proces przechodzenia drzewa DOM i dopasowywania elementów DOM do dyrektyw.

+0

Dzięki DK, w mojej dyrektywie chcę po prostu usunąć removeAttr w niektórych atrybutach, a DOM jest aktualizowany po wywołaniu removeAttr, to dlaczego mam zadzwonić do $ compile? – liontale

3

Myślę, że głównym powodem tego jest fakt, że używasz zdarzenia kliknięcia w elemencie, w którym stosujesz dyrektywę, zamiast definiować to wydarzenie bezpośrednio w dyrektywie. Dzięki temu uzyskujesz kliknięcie z elementu przycisku, ale także kliknięcie z kontrolera dyrektywy.

To, co robią kompilacje $ USD, po wywołaniu na podstawie znaczników, wytworzy funkcję, której możesz użyć do powiązania znaczników z określonym zakresem (czym Angular nazywa funkcję łączenia), dlatego domyślnie sugerowałem użycie linku, jak sądzę. W tym konkretnym przypadku oznacza to, że używasz zdarzenia bezpośrednio w przycisku elementu, ale następnie łączysz je ponownie z zakresem dyrektywy, używając $ compile. Chyba dlatego otrzymujesz wiadomość dwa razy.

Ponieważ nie wiem, czy jest to jasne, uzyskałem informacje z tego linku http://odetocode.com/blogs/scott/archive/2014/05/07/using-compile-in-angular.aspx, gdzie jest to lepiej wyjaśnione.

Tutaj także JSFiddle, gdzie można zobaczyć, jak działa (fragment powyższego artykułu).

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