2015-10-10 3 views
1

Я работаю с $http в 1.4.7.

Мне нужно отделить свои контроллеры от любых $http запросов. Таким образом, я создал службу следующим образом:

app.service('MyService', function($http, $q, $rootScope) { 

    this.getcustomers = function() { 
    var deferred = $q.defer(); 
    $http({ 
     method: 'GET', 
     url: 'http://call/to/rest/api' 
    }).then(function successCallback(response) { 
     deferred.resolve(response.data); 
    }, function errorCallback(response) { 
     deferred.reject(error); 
    }); 
    return deferred.promise; 
    }; 

}); 

Тогда в моем контроллере я называю это сервис следующим образом:

app.controller('registerationCtrl', ['$scope', '$http', 'MyService', '$location', function($scope, $http, MyService, $location) { 
    $scope.custlst = []; 

    $scope.getcustomers = function() { 

    var x = MyService.getcustomers().then(function(data) { 
     $scope.custlst = data; 
    }, function(err) { 
     alert(err); 
    }); 

    } 


}]); 

Теперь, выше не работает он дает мне ReferenceError ошибки в настоящее время определены и указывает на функцию errorCallback в сервисе.

Вопрос 1: Что не так со сценарием? Вопрос 2: Важно ли использовать $q? Помните, что сервер может быть медленным.

Спасибо.

+0

'error' переменная внутри' errorCallback' не определен, следовательно, ошибка ... вы, вероятно, имел в виду, чтобы сделать 'функцию errorCallback (ошибка) {...}' вместо 'function errorCallback (response) {...}'. И нет, вам не нужно было использовать '$ q' - вы могли бы просто вернуть обещание, уже сгенерированное' $ http' –

+0

Yup, что исправил его благодаря помощнику – user3052526

ответ

2

На самом деле вам не нужно использовать $q, чтобы создать обещание. $http сделать это для вас уже, так что вы можете просто сделать:

app.service('MyService', function($http) { 
    this.getcustomers = function() { 
    return $http.get({ 
     method: 'GET', 
     url: 'http://call/to/rest/api' 
    }); 
    }; 
}); 

Тогда вы можете цепи ваш MyService.getcustomers с .then() легко и обработать ответ так:

MyService.getcustomers.then(
    function(data) { 
    //do something with data 
    }, 
    function(error) { 
    //do something with error 
    } 
); 

Я думаю, что вы должны смотреть at this post Я хочу лучше понять, как работает и работает обещание.

EDIT: обновление устаревшего звонка до $http.

+0

Отлично, поэтому сервис хорош, но почему он рекомендуется на сайт AngularJS использовать $ q и откладывается, если $ http возвращает его. Можете быть глупыми, чтобы спросить, но я не могу опустить голову. – user3052526

+2

Заметьте, что 'success' и' error' устарели в '$ http' docs в пользу использования обещания' then' – charlietfl

+0

Да, они устарели. Плохо, я обновлю код. – Freezystem

1

Ну, в AngularJS Документах https://docs.angularjs.org/api/ng/service/$http

Deprecation Уведомление в $ HTTP методы наследство обещают успех и ошибки устарели. Вместо этого используйте стандартный метод. Если $ httpProvider.useLegacyPromiseExtensions установлено в false, то эти методы будут вызывать ошибку $ http/legacy.

Вам не нужно использовать обещание $ q.

Как вы используете запрос GET, вы можете использовать метод ярлыков для выполнения запроса GET .: $http.get();.

Таким образом, вы можете попробовать что-то вроде этого:

MyService услуги: Только вам нужно $http обслуживание.

app.service("MyService", ["$http", function ($http) { 
    this.getcustomers = function() { 
     return $http.get("http://call/to/rest/api"); 
    }; 
}]); 

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

registerationCtrl контроллер: Вам нужны $scope, MyService и location услуги.

app.controller("registerationCtrl", ["$scope", "MyService", "$location", function ($scope, MyService, location) { 
     $scope.custlst = []; 

     $scope.getcustomers = function() { 
      MyService.getcustomers().then(function (response) { 
       $scope.custlst = response.data; 
      }, function (err) { 
       alert(err); 
      }); 
     }; 
    }]); 
}]); 
+1

OP не использует 'success' или' error' – charlietfl

+0

Используя этот способ, сервис можно использовать в любом контроллере. –

1

Как я уже говорил в комментариях, ошибка вы видите, это связано с error переменной не объявленной внутри функции errorCallback.

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

this.getcustomers = function() { 
    return $http({ 
     method: 'GET', 
     url: 'http://call/to/rest/api' 
    }) 
    // pre-process the HTTP response and return the data 
    .then(function(response) { 
     return response.data; 
    }) 
    // If needed, create a custom error to hide HTTP details from caller 
    // otherwise, don't include .catch - the original error will "bubble up" 
    .catch(function(error) { 
     return $q.reject({ 
     msg: "something broke" 
     }); 
    }); 
}; 

Тогда, клиент может быть использован, как вы хотели:

MyService.getcustomers() 
    .then(function(data) { 
    $scope.customers = data; 
    }) 
    .catch(function(error) { 
    console.log(error.msg); 
    })