AngularJS factory http возвращается пустым
Я пытаюсь AngularJS в первый раз. Я получаю данные JSON из запроса http-get с помощью factory, но объект возвращается пустым, прежде чем будет выполнен запрос ajax.
Factory:
myDemo.factory('photosFactory', function($http) {
var photos = [];
var factory = {};
factory.getPhotos = function() {
$http({
url: 'content/test_data.json',
method: 'GET'
}).success(function(data, status, headers, config) {
photos = data;
return photos;
});
};
return factory;
});
Контроллер:
controllers.AppCtrl = function($scope, $location, $http, photosFactory) {
$scope.photos = [];
init();
function init() {
$scope.photos = photosFactory.getPhotos();
}
};
Это то, что я придумал. Когда контроллер устанавливает $scope.photos, значение пустое, как если бы он возвращал массив фотографий, прежде чем он заполнится с ответом ajax.
Ответы
Ответ 1
Вы должны изменить свой код, чтобы вернуть обещание, и использовать значение в pls контроллера, см. фиктивный измененный код
myDemo.factory('photosFactory', function($http) {
return{
getPhotos : function() {
return $http({
url: 'content/test_data.json',
method: 'GET'
})
}
}
});
и контроллер -
controllers.AppCtrl = function($scope, $location, $http, photosFactory) {
$scope.photos = [];
photosFactory.getPhotos().success(function(data){
$scope.photos=data;
});
};
Ответ 2
Использование библиотеки q обещаний означает, что ваша функция успеха может оставаться в вашей службе:
app.factory('Data', function ($http, $q) {
return {
ajaxItems: function () {
var deferred = $q.defer();
$http({ method: "POST", url: "/Home/GetSearchResults" })
.success(function (data, status, headers, config) {
deferred.resolve(data);
}).error(function (data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
}
}
});
app.controller('ResultsCtrl', ['$scope', 'Data', function ($scope, Data) {
$scope.get = function () {
$scope.items = Data.ajaxItems();
//the model returns a promise and THEN items
$scope.items.then(function (items) {
$scope.items = items;
}, function (status) {
console.log(status);
});
};
}]);
Ответ 3
Использование $resource
позволит вам достичь того, чего вы хотите, плюс даст вам гораздо больше контроля по сравнению с $http
(Не забудьте включить ngResrouce
в качестве зависимости от вашего приложения.)
myDemo.factory('photosFactory', function($resource) {
var factory = {};
factory.getPhotos = $resource('content/test_data.json', {}, {
'query': {method: 'GET', isArray: true}
});
return factory;
});
controllers.AppCtrl = function($scope, $location, $http, photosFactory) {
$scope.photos = [];
init();
function init() {
$scope.photos = photosFactory.getPhotos.query();
}
};