2013-12-16 11 views
13

Ich bin so grün bei Angular, ich bin nicht einmal sicher, dass ich eine Suche nach dieser richtig strukturiert habe. Die ganze Richtlinie und die Terminologie der Dienste verwirren mich immer noch, aber das ist nicht meine Frage.AngularJS - Aufruf einer Controller-Funktion von einem Service

Ich habe diese ausgezeichneten Artikel Serie vorne lese nach hinten: http://www.ng-newsletter.com/posts/beginner2expert-how_to_start.html

, weshalb ich an dieser Stelle bin in meiner Anwendung. Und warum ich weiß, meine Frage bezieht sich mehr auf die Beziehung zwischen Diensten und Controllern. Eher als Syntax-bezogen.

So, hier ist eine Übersicht über die App:

ich einen Controller haben. Dies geht ab und erhält eine Reihe von Farmdaten für den Benutzer, der einen AJAX-Aufruf an eine PHP-Datei verwendet, und zeigt es auf dem Bildschirm mit seinem eigenen $ scope an.

Sie werden sehen, ich injiziere etwas namens "commonControls". Dies war ein Modul, das ich erstellt habe, um Steuerelemente zu halten, die von mehreren Controllern wiederverwendet werden. In diesem Fall wird ein Dropdown-Feld, das eine Liste der Betriebe enthält der Benutzer Zugriff hat (auch durch einen AJAX-Aufruf erhalten):

var commonControlsApp = angular.module('commonControls', []); 

commonControlsApp.controller('farmSelectorCtrl', ['$scope', '$http',function($scope, $http) { 

    $scope.farmSelectorCtrl ={} 

    // Change entire farm view when a different farm is selected 
    $scope.farmSelectorCtrl.switchUserFarm = function() { 
     var farmId = $scope.farmSelectorCtrl.selectedUserFarm; 
     $scope.masterCtrl.loadFarms(farmId); // !!! Direct link to masterCtrl 
    }; 

    // Get a list of the user's farms 
    $http.post('/service/userfarms').success(function (data) { 
     $scope.farmSelectorCtrl.userFarms = data.getFarmsPerUserResult.farmIds; 
    }); 

}]); 

Dies funktioniert gut. Aber wie Sie sehen können, ist der farmSelector direkt mit masterCtrl verbunden. Und das Verhalten dieser loadFarmData-Funktion ist spezifisch für diesen Controller. Mit anderen Worten, es werden nur Dinge ausgeführt, die für diese Seite gelten.

Die Sache ist, dieser farmSelector wird auf anderen Seiten verwendet werden. Und das genaue Verhalten eines Änderungsereignisses wird für jede Seite unterschiedlich sein. Ich kämpfe darum, herauszufinden, wo dieses Verhalten liegen sollte. Und wie es heißen würde, abhängig vom Controller, der den farmSelector verwendet.

Der Artikel, den ich oben verlinkt habe, schlägt vor, dass dieser farmSelector in einem Dienst sein sollte, damit er woanders wiederverwendet werden kann. Aber ich bin immer noch verwirrt darüber, wie Sie einem generischen Dienst eine bestimmte Aktion zuweisen können, die ausgelöst werden soll, wenn ein Ereignis ausgelöst wird.

Antwort

11

Ich empfehle auch einen Service, aus dem gleichen Grund, den der Artikel vorschlägt. Es hat auch eine gute Antwort auf Ihr Problem.

Der technische Ausdruck für was Sie wollen, ist eine Calback-Funktion. Es ist genau eine bestimmte Aktion, die ausgeführt werden soll, wenn ein Ereignis ausgelöst wird, und der Abschnitt "Dienste" des Artikels bietet ein gutes Beispiel dafür.

Werfen Sie einen Blick auf diesen Abschnitt des Artikels Services (die ich habe zu den wichtigen Teilen abgespeckte)

angular.module('myApp.services', []) 
    .factory('githubService', ['$http', function($http) { 

    var doRequest = function(username) { 
     return $http({ 
     url: 'https://MySuperURL.com/getTheData' 
     }); 
    } 

    return { 
     events: doRequest 
    }; 

}]); 

Deshalb haben wir jetzt einen Dienst war, rief githubService, die eine Methode hat: events (die für doRequest wirklich nur ein anderer Name ist;. ich den Umbenennungs gehalten, so dass es mit dem Artikel des Code entsprechen würde)

hinter den Kulissen Versteckt hier ist die $q API, die manchmal als das bezeichnet wird "Versprechen" API. Die Funktion $http gibt ein "Versprechen" -Objekt zurück, das wirklich nur eine Möglichkeit für den Code ist, zu verfolgen, was passieren soll, wenn das "Versprechen" gemacht wird.Betrachten wir zum Beispiel diesen nächsten Code (wiederum modifiziert von der Artikelversion):

app.controller('ServiceController', ['$scope', 'githubService', 
function($scope, githubService) { 

    // uses the $http service to call the GitHub API 
    // and returns the resulting promise 
    githubService.events(newUsername) 
    .success(function(data, status, headers) { 
     // do magic stuff with the result 
     // (which is in the data param) 
     $scope.events = data.data; 
    }) 
}); 

}]);

Hier findet die "Magie" statt. Schauen Sie sich den Anruf an , und Sie werden sehen, dass sie tatsächlich eine function übergeben, die ausgeführt werden soll, wenn die Anfrage funktioniert. Die Funktion hat weiterhin Zugriff auf alle Variablen in ServiceController aufgrund der Schließung, so dass $scope und andere Variablen verwendet werden dürfen. Es ist jedoch sehr gut möglich, in jedem Controller eine andere success()-Methode zu schreiben, indem jedes Mal eine andere Funktion übergeben wird, wodurch mehrere Controller unterschiedliche Aktionen ausführen können. Wenn die Anfrage beendet ist, ruft sie jede success Funktion auf, die sie erhalten hat.

Sie könnten diesem Codebeispiel folgen und ein funktionierendes Modell erhalten, aber ich schlage auch vor, dass Sie einen Blick auf $q in angular werfen, und schauen Sie sich auch diesen Artikel über callback functions an. Sie müssen beide verstehen, um wirklich zu verstehen, was vor sich geht, aber die gute Nachricht ist, dass sie beide häufig in eckigen Klammern verwendet werden, also wird es Ihre Zeit wert sein.

+0

Ich wünschte, ich sah diese Antwort vor ein paar Stunden Kopf kratzen, wie das geht. Vielen Dank für die Mühe –

Verwandte Themen