Подтвердить что ты не робот

AngularJS - вызов функции контроллера из службы

Я так зеленый в Angular, я даже не уверен, что правильно структурировал поиск. Вся директива и терминология обслуживания все еще меня путают, но это не мой вопрос.

Я прочитал эту замечательную серию статей позади: http://www.ng-newsletter.com/posts/beginner2expert-how_to_start.html

Вот почему я сейчас нахожусь в своем приложении. И почему я знаю, что мой вопрос больше связан с взаимоотношениями между службами и контроллерами. Вместо синтаксиса.

Итак, вот обзор приложения:

У меня есть один контроллер. Это отключается и получает кучу данных фермы для пользователя, использующего вызов AJAX в PHP файл, и отображает его на экране, используя собственную область видимости.

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

masterApp.controller('MasterCtrl', ['$scope','$http', '$filter', 'commonFarmSelector', 
    function($scope, $http, $filter, commonFarmSelector){

        ...

        $scope.masterCtrl.loadFarmData = function(farmId) {
            var postdata = {
               "farmId":farmId
            };

            $http.post('/service/farmproduction', postdata).success(function (data) {
                // Do stuff with the $scope using data
            }
        }

        $scope.masterCtrl.loadFarms();
}

Вы увидите, что я впрыскиваю что-то под названием commonControls. Это был модуль, который я создал для хранения элементов управления, которые будут повторно использоваться несколькими контроллерами. В этом случае выпадающее поле, содержащее список ферм, к которым пользователь имеет доступ (также полученный по вызову AJAX):

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 farms
    $http.post('/service/userfarms').success(function (data) {
        $scope.farmSelectorCtrl.userFarms = data.getFarmsPerUserResult.farmIds;
    });

}]);

Это прекрасно работает. Но, как вы можете видеть, farmSelector напрямую связан с masterCtrl. И поведение этой функции loadFarmData специфично для этого контроллера. Другими словами, он будет делать только то, что относится к этой странице.

Дело в том, что этот farmSelector будет использоваться на других страницах. И точное поведение события изменения будет отличаться для каждой страницы. Поэтому я изо всех сил пытаюсь разобраться, где должно сидеть такое поведение. И как он будет называться зависимым от контроллера с помощью farmSelector.

В статье, которая была приведена выше, предлагается, что этот фермерский выбор должен быть в службе, чтобы его можно было повторно использовать в другом месте. Но я все еще смущен тем, как вы могли бы дать универсальную услугу определенное действие, которое нужно предпринять, когда срабатывает событие.

4b9b3361

Ответ 1

Я очень рекомендую услугу, по той же причине, о которой предлагает статья. Он также имеет отличный ответ на вашу проблему.

Технический термин для того, что вы хотите, это функция calback. Это конкретное действие, которое необходимо предпринять, когда событие инициируется, а раздел "Службы" статьи является хорошим примером того, как это сделать.

Взгляните на этот раздел статьи "Услуги" (который я урезал до важных частей)

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

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

    return {
      events: doRequest
    };

}]);

Итак, теперь у нас есть услуга, называемая githubService, которая имеет один метод: events (это действительно просто другое имя для doRequest; я сохранил переименование так, чтобы оно соответствовало статье код).

Скрытым здесь за кулисами является API $q, который иногда называют API-интерфейсом "обещание" . Функция $http возвращает объект "обещание" , что на самом деле является способом для кода отслеживать, что должно произойти, когда "обещание" будет выполнено. Например, рассмотрим следующий код (опять же, измененный в версии статьи):

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;
    })
});

}]);

Здесь происходит "волшебство". Посмотрите на вызов success(), и вы увидите, что они фактически передают function, который должен запускаться, когда запрос работает. Функция все еще имеет доступ ко всем переменным в ServiceController из-за закрытия, поэтому разрешено использовать $scope и другие переменные. Тем не менее, очень легко написать другой метод success() в каждом контроллере, каждый раз передавая разные функции, что позволяет нескольким контроллерам выполнять разные действия. Когда запрос завершится, он вызовет каждую функцию success, которую он дал.

Вы можете выполнить этот пример кода и получить рабочую модель, но я также предлагаю вам взглянуть на $q в angular, а также взгляните на эту статью о функции обратного вызова. Вам нужно понять, как реально получить то, что происходит, но хорошей новостью является то, что они оба используются довольно часто в angular, поэтому он будет стоить вашего времени.