Наилучший подход к разделению задач для задач $http между контроллером и службой

(работает с Angular 1.5)

Прочитал множество статей (некоторые свежие, некоторые старые/устаревшие) на тему $http-запросов, промисов и разделения проблем, и в настоящее время я экспериментирую с приведенным ниже примером (Plunker здесь).

Надеялся получить отзыв о следующей умственной головоломке, пожалуйста:

Что касается запроса $http.get(), достаточно ли я сделал, чтобы обеспечить разделение проблем между контроллером и внедрённым сервисом?

Я понимаю, что контроллеры могут не нести ответственность за обработку обратного вызова ошибки, но я думал примерно так: если произошла ошибка http (например, сервер не работает), то, безусловно, контроллер захочет выполнить некоторые непредвиденные задачи, например. отменить загрузку счетчика, перенаправить на страницу с ошибкой и т. д.

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

( function () {

var app = angular.module('myApp', []);

app.service('userService', ['$http', '$q', function($http, $q) {

    this.getUsers = function(url){

        return $http.get(url).then(
            function(response) { // success
                return response.data;
            })['catch']( // error ('catch' workaround for IE8)
                function(response) {
                    return $q.reject(response);
                }
            );

    };

}]);

app.controller('usersCtrl', ['$scope', 'userService', function($scope, userService){

    $scope.getUsersData = function(url) {

        userService.getUsers(url).then(
            function(data){ // success - set $scope data, cancel spinner, etc
                console.log(data);
            },
            function(error){ // error - cancel spinner and display error messages, or possibly redirect to custom error page, etc
                console.log(error);
            }
        );

    };

    $scope.getUsersData('dummyData.htm');

}]);

}());


person I am me    schedule 27.10.2016    source источник


Ответы (2)


Контроллер является ответственным за обработку обратного вызова ошибки из вызова службы (например, перенаправление на какую-либо страницу с ошибкой...).
Ваш пример использования идеален: служба просто возвращает response.data в в случае успеха или $q.reject(response) в случае ошибок, а контроллеры обрабатывают случаи успеха и ошибки...

person MarcoS    schedule 27.10.2016

Похоже на хорошее разделение проблем. Я сделал именно так, как вы описали в одном из моих проектов :)

Вопросы. Почему бы вам не указать URL непосредственно в функции getUsers службы? Это меняется?

Кстати: вы можете просто вернуть обещание из angular..

    this.getUsers = function() {
       return $http.get(this.appConfig.baseApiUrl + "/users");
    };

... и используйте обратные вызовы успеха и ошибки:

$scope.getUsersData = function() {    
        userService.getUsers().then(
           (function(response) { // success callback
                console.log(response.data);
            }),
           (function(error) { // error callback
                console.log(error);
            })
       );   
    };

Вы получаете данные непосредственно из ответа. И выглядит гораздо чище ;)

person Daniel Bauer    schedule 27.10.2016
comment
Спасибо за дополнение - с таким количеством статей по теме и разнообразием мнений иногда трудно найти ясность или уверенность в своем решении. Да, параметр url на данный момент предназначен только для целей тестирования (я планировал использовать app.constant() для установки этого значения среды в дальнейшем). Я избегал использования методов success и error, потому что я читал, что они обесценились... так ли это? - person I am me; 27.10.2016
comment
Я знаю эту борьбу, есть много нечистых туториалов. Я бы не стал указывать весь URL-адрес как постоянный, потому что если у вас есть несколько сервисов, которые извлекают данные из конечной точки, у вас в конечном итоге будет много констант URL-адресов. Я рекомендую создать объект AppConfig, который содержит свойство apiBaseUrl (например, «localhost: 1234»), и жестко указать конкретный URL-адрес в вашей службе, например «$ http.get (this.apiBaseUrl + /users). Вы можете поменять местами AppConfig, если вы работаете продуктивно) О, да, вы правы .. (я забыл об этом) методы успеха и ошибки были устаревшими. обновляю свой ответ.. - person Daniel Bauer; 27.10.2016