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 を a としてdirective
、または 1.5 a としてバンドルし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);
古い回答 (14 年 7 月 23 日 20:26)
値を返す前に値が設定されないためです。Service(factory) を再構築したいかもしれませんが、$q を使用して promise を処理することもできます。次の例を検討してください。
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();
}]);
http-request などの非同期タスクを処理しているときに $q を使用するのが一般的です。