2012-10-23 14 views
10

Hallo da habe ich diese "confirmable" Taste Richtlinie, die ich auf,angular.js: Wie übergibt man ngclick vom ursprünglichen dom an dom?

Den HTML-Code arbeite, die die Richtlinie 'confirmable'

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

die Richtlinie auslösen: (Coffee)

angular.module('buttons',[]) 

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

Also das Endergebnis ich möchte mit dieser Richtlinie erzeugt, um zu sehen ist

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

Bisher habe ich es mit einer Verbindungsfunktion in der Richtlinie

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 

Aber ich habe durch die Richtlinie Dokumentation zur Arbeit wieder weg und fand den Umfang Eigenschaft mit den =, @, & Betreibern aber ich bin mir wirklich unsicher, ob sie das sind, was ich brauche. Dann gibt es diese Eigenschaften, die ich noch verstehen muss, aber im Moment scheint es auch nicht hilfreich zu sein. Also, während meine Link-Funktion für den Moment den Trick macht, aber ich dachte, ich sollte fragen, ob eckig eine elegantere Lösung bietet.

Danke!

Antwort

6

Es klingt für mich wie Sie eine Methode aus einem übergeordneten Bereich aus Ihrer Richtlinie anrufen möchten ...

Ich habe zusammen JavaScript ein Plunk here

(Sorry, Ich mag setzen ... also hier geht)

Hier ist Ihr Eltern-Controller.

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

dann Ihre Auszeichnungs

<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> 

Und Ihre Richtlinie Erklärung:

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

Das Bit in der scope Erklärung in Ihrer Richtlinie Definition ist es, was den Umfang Funktionsreferenz Eltern bindet an Ihre Anwendungsbereich der Richtlinie, so dass es bei Klick aufgerufen werden kann. Das ist, was die & da ist.

+1

ich, das ist sehr nützlich, sehen, zu Funktionen herum wie dies passieren wird. Nur neugierig, können Sie Argumente an foo() übergeben? und wie wird es auf die Richtlinie übertragen? –

+0

Ja, Sie können Argumente übergeben. Im Allgemeinen "tröpfeln" die Dinge von der Direktive zu den Eltern, nicht umgekehrt. Wenn Sie vor dem Aufrufen des Verweises auf die Funktion des Elternteils etwas für die Direktive ausführen wollten, dann würden Sie diesen Aufruf einfach in eine andere Bereichsfunktion in der Controller-Deklaration der Direktive einfügen. –

+1

Hmm. Ist es nicht empfehlenswert, 'ng-click' erneut zu verwenden, da es so allgemein bekannt ist? Es funktioniert in Ihrem Beispiel, aber wenn Sie die 'replace: true'-Option für Ihre Anweisung verwenden, bricht sie ab. Ich habe keine Idee warum. = [ – Langdon

1

Sie machen es richtig. Controller dienen zur gemeinsamen Nutzung von Funktionen unter Richtlinien. Du brauchst hier keinen. Auch in diesem Fall ist so einfach, dass man nicht einmal eine Link-Funktion benötigen:

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

Kopieren der Richtlinie Attribut in der Verknüpfungsstufe über nichts tun, so weit wie Angular betroffen ist. Sie haben nur eine Schaltfläche mit einem ng-click Attribut, aber das wurde hinzugefügt, nachdem Angular das DOM verarbeitet hat.

Beachten Sie auch, element als der zweite Parameter der Link-Funktion ist bereits JQLite (und vermutlich auch volle jQuery, wenn Sie das auch verknüpft haben.) Keine Notwendigkeit, es zu jQuery.

Auch in Bezug auf isolieren Bereiche (die =, @ und & Sie erwähnen). Es ist eine schöne, elegante Syntax, aber der große Nachteil ist, dass alle anderen Direktiven für dasselbe Element vom Gültigkeitsbereich isoliert werden. Wenn Sie also mit ngModel arbeiten möchten, können Sie einen isolate-Bereich nicht verwenden. Selbst in diesem Fall, wenn Sie einen isolieren Bereich verwenden, klicken Sie auf die Schaltfläche. Weil es versuchen wird, den Ausdruck auszuwerten, der Dinge enthält, die nicht explizit in der Eigenschaft scope {} deklariert sind.

1

Wenn Sie das DOM in der Verknüpfungsstufe manipulieren und seinen Elementen eine eckige Logik hinzufügen möchten, müssen Sie die betreffenden Elemente kompilieren. Lassen Sie angular inject $compile und rufen Sie es auf, nachdem Sie die Verarbeitung des DOM abgeschlossen und Ihre ng-*-Anweisungen hinzugefügt haben.

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

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