it-swarm.com.de

Rückruffunktion innerhalb der Direktive attr in verschiedenen attr

Also habe ich diese Direktive sagen, mySave, es ist so ziemlich alles

app.directive('mySave', function($http) {
   return function(scope, element, attrs) {
      element.bind("click", function() {
          $http.post('/save', scope.data).success(returnedData) {
              // callback defined on my utils service here

              // user defined callback here, from my-save-callback perhaps?
          }
      });
   }
});

das Element selbst sieht so aus

<button my-save my-save-callback="callbackFunctionInController()">save</button>

callbackFunctionInController ist vorerst nur 

$scope.callbackFunctionInController = function() {
    alert("callback");
}

wenn ich console.log()attrs.mySaveCallback in my-save-Direktive besitze, gibt es mir nur eine Zeichenfolge callbackFunctionInController(). Ich las irgendwo , dass ich dies $ parse und es wäre gut, also versuchte ich $parse(attrs.mySaveCallback), was mir etwas Funktion gab Kaum der, nach dem ich gesucht hatte, gab mich zurück

function (a,b){return m(a,b)} 

Was mache ich falsch? Ist dieser Ansatz von Anfang an fehlerhaft?

38
fxck

Was also der beste Weg zu sein scheint, ist die Verwendung des isolierten Bereichs, wie von ProLoser vorgeschlagen

app.directive('mySave', function($http) {
   return {
      scope: {
        callback: '&mySaveCallback'
      }
      link: function(scope, element, attrs) {
        element.on("click", function() {
            $http.post('/save', scope.$parent.data).success(returnedData) {
                // callback defined on my utils service here

                scope.callback(); // fires alert
            }
        });
      }
   }
});

Um Parameter zurück an den Controller zu übergeben, tun Sie dies

[11:28] <revolunet> you have to send named parameters 
[11:28] <revolunet> eg my-attr="callback(a, b)" 
[11:29] <revolunet> in the directive: scope.callback({a:xxx, b:yyy})
61
fxck

Es gibt viele Möglichkeiten, was Sie tun. Das ERSTE, was Sie wissen sollten, ist, dass die $http.post() aufgerufen wird, sobald dieses DOM-Element von der Template-Engine ausgegeben wird. Wenn Sie es in eine Wiederholung einfügen, wird der Anruf für jeden neuen Eintrag im Repeater erledigt. Ich vermute, dies ist definitiv nicht das, was Sie wollen. Und wenn ist , dann entwerfen Sie wirklich nicht die richtigen Dinge, da die Existenz von DOM alleine keine Anfragen an das Backend diktieren sollte.

Wie auch immer, direkt auf deine Frage antworten; Wenn Sie die zwar beschissenen Dokumente in $ parse lesen, erhalten Sie einen Bewertungsausdruck. Wenn Sie diese Funktion ausführen, indem Sie den Gültigkeitsbereich für die Auswertung übergeben, wird der aktuelle Status dieses Ausdrucks für den von Ihnen übergebenen Gültigkeitsbereich zurückgegeben. Dies bedeutet, dass Ihre Funktion ausgeführt wird.

var expression = $parse(attrs.mySave);
results = expression($scope); // call on demand when needed
expression.assign($scope, 'newValu'); // the major reason to leverage $parse, setting vals

Ja, es ist anfangs etwas verwirrend, aber Sie müssen verstehen, dass sich ein $ -Bereich in asynchronen Apps ständig ändert. $parse ist nützlicher für einen Verweis auf ein Modell, dem Sie einen Wert zuweisen und nicht nur lesen möchten.

Natürlich möchten Sie vielleicht wissen, wie Sie einen Isolat-Bereich erstellen oder wie Sie einen Ausdruck $eval() erstellen. 

$scope.$eval(attrs.mySave);
12
ProLoser

Sie können . $ Eval verwenden, um eine Anweisung im angegebenen Bereich auszuführen

app.directive('mySave', function($http) {
   return function(scope, element, attrs) {
      $http.post('/save', scope.data).success(returnedData) {
          // callback defined on my utils service here

          // user defined callback here, from my-save-callback perhaps?
          scope.$eval(attrs.mySaveCallback)
      }
   }
});

TD: Demo

Wenn Sie Daten für eine Direktive und einen Controller freigeben möchten, können Sie die bidirektionale Bindung verwenden

app.controller('AppController', function ($scope) {
   $scope.callbackFunctionInController = function() {
      console.log('do something')
   };

   $scope.$watch('somedata', function(data) {
      console.log('controller', data);
   }, true);
});

app.directive('mySave', function($http, $parse) {
   return {
     scope: {
       data: '=mySaveData',
       callback: '&mySaveCallback' //the callback
     },
     link: function(scope, element, attrs) {
       $http.get('data.json').success(function(data) {
         console.log('data', data);
         scope.data = data;
         scope.callback(); //calling callback, this may not be required
       });
     }
   };
});

Demo: Fiddle

9
Arun P Johny
scope: {
    callback: '&mySaveCallback'
}

Das explizite Festlegen des Bereichs könnte eine gute Lösung sein, aber wenn Sie andere Teile des ursprünglichen Bereichs erreichen möchten, können Sie dies nicht, da Sie ihn gerade überschrieben haben. Aus irgendeinem Grund musste ich auch andere Bereiche des Gültigkeitsbereichs erreichen, also verwendete ich dieselbe Implementierung wie ng-click do.

Die Verwendung meiner Direktive in HTML:

<div my-data-table my-source="dataSource" refresh="refresh(data)">

Innerhalb der Direktive (ohne den Geltungsbereich explizit festzulegen):

var refreshHandler = $parse(attrs.refresh);
    scope.$apply(function () {
    refreshHandler( {data : conditions}, scope, { $event: event });
});

Hiermit kann ich die Funktion im Controller aufrufen und Parameter übergeben.

In der Steuerung:

$scope.refresh= function(data){
    console.log(data);
}

Und es druckt die Bedingungen richtig aus.

4
Ferenc Kun
app.directive('mySave', function($http, $parse) {
   return {
     scope: {
       data: '=mySaveData',
       callback: '&' //the callback
     },
     link: function(scope, element, attrs) {
       $http.get('data.json').success(function(data) {
         console.log('data', data);
         if (scope.callback()) scope.callback().apply(data);
       });
     }
   };
});
0
ido niger

Sie sollten ng-click verwenden, anstatt eine eigene Direktive zu erstellen.

0
ProLoser

Das hat bei mir funktioniert

Im View-Skript

<tag mycallbackattrib="scopemethod">

In der Direktive

$scope[attrs.mycallbackattrib](params....);

Es wird korrekt aufgerufen und Parameter werden übergeben, aber es ist vielleicht nicht der beste "Winkelweg", um zu arbeiten.

0
Sergio Rinaudo