AngularJS-Direktive, die eine Funktion mit mehreren Argumenten bindet

72

Ich habe Probleme beim Binden einer in einem Controller definierten Funktion mit einer Rückruffunktion in einer Direktive. Mein Code sieht folgendermaßen aus:

In meinem Controller:

$scope.handleDrop = function ( elementId, file ) {
    console.log( 'handleDrop called' );
}

Dann meine Anweisung:

.directive( 'myDirective', function () {
    return {
      scope: {
        onDrop: '&'
      },
      link: function(scope, elem, attrs) {
        var myFile, elemId = [...]

        scope.onDrop(elemId, myFile);
      }
    } );

Und auf meiner HTML-Seite:

<my-directive on-drop="handleDrop"></my-directive>

Ich habe kein Glück mit dem obigen Code. Nach dem, was ich in verschiedenen Tutorials gelesen habe, soll ich die Argumente auf der HTML-Seite angeben.

Joseph Paterson
quelle

Antworten:

84

Es gibt einen kleinen Fehler in Ihrem Code. Bitte versuchen Sie den folgenden Code und er sollte für Sie funktionieren

<!doctype html>
<html ng-app="test">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script>

  </head>
 <body ng-controller="test" >    


<!-- tabs -->
<div my-directive on-drop="handleDrop(elementId,file)"></div>

 <script>
     var app = angular.module('test', []);

     app.directive('myDirective', function () {
         return {
             scope: {
                 onDrop: '&'
             },
             link: function (scope, elem, attrs) {
                 var elementId = 123;
                 var file = 124;
                 scope.onDrop({elementId:'123',file:'125'});

             }
         }
     });

     app.controller('test', function ($scope) {
         alert("inside test");
         $scope.handleDrop = function (elementId, file) {
             alert(file);
         }
     });

   </script>
</body>


</html>
Ajay Beniwal
quelle
2
Wo ist dieses Verhalten in der Angular-Dokumentation definiert?
Nick Radford
1
Es scheint kein aktuelles Thema in den Dokumenten zu geben, aber das Thema ist die Verknüpfungsfunktion von Anweisungen, docs.angularjs.org/guide/directive
tommybananas
3
Anscheinend müssen die Parameternamen genau mit dem Markup übereinstimmen. Ich frage mich, ob dies die Minifizierung überleben würde.
TrueWill
@TrueWill Ich denke, AngularJS kämpft mit der traditionellen Minifizierung insgesamt, aber es hat ein ngmin-Modul, das das gleiche tut
Joseph Paterson
3
@JosephPaterson Laut der Webseite ist ngmin zugunsten von ng-annotate veraltet . Vielen Dank!
TrueWill
123

Alternative Methode, die die Minifizierung überlebt

Lassen Sie Ihr HTML wie es war:

<my-directive on-drop="handleDrop"></my-directive>

Ändern Sie den Anruf in:

scope.onDrop()('123','125')

Beachten Sie die zusätzlichen öffnenden und schließenden Klammern für onDrop. Dadurch wird die Funktion instanziiert, anstatt den Funktionscode einzufügen.

Warum ist es besser?

  1. handleDrop()Wenn Sie die Namen der Parameter in der Definition ändern (oder sogar weitere hinzufügen, wenn Sie richtig damit umgehen), werden Sie nicht jede der Direktiveninjektionen im HTML ändern. viel trockener.

  2. Wie @TrueWill vorgeschlagen hat, bin ich mir fast sicher, dass die anderen Lösungen die Minifizierung nicht überleben werden, während der Code auf diese Weise bei maximaler Flexibilität bleibt und namenunabhängig ist.

Ein weiterer persönlicher Grund ist die Objektsyntax, mit der ich viel mehr Code schreibe:

functionName({xName: x, yName: y}) // (and adding the function signature in every directive call)

Im Gegensatz zu

functionName()(x,y) // (zero maintenance to your html)

Ich habe diese großartige Lösung hier gefunden .

Nuriel
quelle
Dies funktionierte auch für mich, aber ich hatte ein Problem mit der Objektnotation. Explizite Verwendung von Klassen in Typescript. Dieser Kommentar hat mir geholfen, das Problem zu beheben.
Justin Boyson
Das funktioniert. Ich habe "TypeError: Der Operator 'in' kann nicht verwendet werden, um nach x in y zu suchen" erhalten, indem ich das getan habe, was der Joe war.
Nilloc