Поскольку за 18 месяцев можно многому научиться, я хотел бы обновить свой ответ. В приведенном ниже примере показано, как я решил бы проблему сегодня. (См внизу оригинальное решение)
function dataFactory($http) {
//Service interface, all properties and methods will be set to this object.
var dataFactory={};
//Instead of using $q, the function will just return the http-promise containing the response data.
dataFactory.getItems=function() {
return $http
.get('data.json')
.then(function(response) {
return response.data;
});
}
//Return object containing the service interface.
return dataFactory;
}
//Use $inject property to specifiy your DI objects, rather than using array syntax.
dataFactory.$inject=['$http'];
function firstController(DataFactory) {
//Use this with controllerAs instead of injecting $scope.
var vm=this;
vm.items=[];
DataFactory
.getItems()
.then(function(items) {
vm.items=items;
}, function(err) {
//error handler
alert("Got an error");
})
}
//same here, use $inject property.
firstController.$inject=['dataFactory'];
angular
.module('testApp', [])
.factory('DataFactory', dataFactory)
.controller('FirstController', firstController);
И HTML
<!-- Use controller as syntax -->
<div ng-controller="firstController as first">
<ul>
<!-- Reference the controller by value given in controller as statement -->
<li ng-repeat="item in first.items">{{item.name}}</li>
</ul>
</div>
Вот как бы я написал код. Тем не менее, это не то, как я бы это решил. Я бы не стал вносить никаких изменений в службу данных, но я бы изменил реализацию контроллера. Либо я бы resolve the items data
через роутер, либо связал бы контроллер и html как directive
, либо как 1.5 как component
.
Использование директивы
function itemsDirective() {
function controller(DataFactory) {
var vm=this;
vm.items=[];
DataFactory
.getItems()
.then(function(items) {
vm.items=items;
}, function(err) {
//error handler
alert("Got an error");
})
}
controller.$inject=['dataFactory'];
return {
restrict:'E',
template:'<div ng-controller="firstController as first">
<ul>
<li ng-repeat="item in first.items">{{item.name}}</li>
</ul>
</div>',
controller: controller,
controllerAs: 'first'
}
}
angular
.module('testApp')
.directive('itemsDirective', itemsDirective);
Старый ответ (23 июль 2014, в 20:26)
Потому что значение не устанавливается до того, как оно вернет свое значение. Сказав это, вы, возможно, захотите реструктурировать свою службу (фабрику), также используйте $q для обработки обещания. Рассмотрим следующий пример:
var App = angular.module('testApp', []);
App.factory('DataFactory', ['$http', '$q', function($http, $q) {
var getItems = function() {
var deffered = $q.defer();
$http.get('data.json').success(function(data) {
deffered.resolve(data);
});
return deffered.promise;
};
return {
getItems: getItems
};
}]);
App.controller('firstCtrl', ['$scope', 'DataFactory',function($scope, DataFactory) {
$scope.items = DataFactory.getItems();
}]);
Обычной практикой является использование $q при работе с асинхронными задачами, такими как http-запрос.
person
cbass
schedule
23.07.2014