私は次のangularjsコードを持っています:
$scope.clients = commonFactory.getData(clientFactory.getClients());
if ($scope.clients.length > 0) {
$scope.sampleForm.ClientId = $scope.clients[0].ClientId;
}
また、commonFactoryのgetData関数:
factory.getData = function (method) {
method.then(function (response) {
return response.data;
}, function (error) {
$rootScope.alerts.Push({ type: 'error', msg: error.data.ExceptionMessage });
});
};
問題は、非同期呼び出しのためにその行にヒットしたときに$ scope.clients.lengthが定義されていないことです。
$ scope.clientsが割り当てられていることがわかるまで、長さのチェックを行わない方法はありますか?私はこのようなものを見ました:
$scope.clients = commonFactory.getData(clientFactory.getClients()).then(function () {
if ($scope.clients.length > 0) {
$scope.sampleForm.ClientId = $scope.clients[0].ClientId;
}
});
then
の約束をチェーンしようとしていますが、サイコロはありません...ここでの目標は、エラーをキャッチするための定型コードの束を避けるためにgetDataメソッドを持つことです。
これは、約束が最も基本的な状況です。非同期操作の開始時にvar deferred = $q.defer()
でプロミスを作成し、非同期操作の完了時にdeferred.resolve(result)
でプロミスを解決し、関数で_deferred.promise
_を返すだけです。 Angularの非同期メソッドはこれを内部で行い、すでにpromiseを返します。そのため、$q.defer()
で新しいpromiseを作成するのではなく、同じpromiseを返すことができます。約束を返すものに_.then
_を付加できます。さらに、then
関数から値を返す場合、その値はthen
チェーンが継続できるようにプロミスにラップされます
_angular.module('myApp', [])
.factory('myService', function($q, $timeout, $http) {
return {
myMethod: function() {
// return the same promise that $http.get returns
return $http.get('some/url');
}
};
})
.controller('myCtrl', function($scope, myService) {
myService.myMethod().then(function(resp) {
$scope.result = resp.data;
});
})
_
そして、ここでチェーンのもう少し楽しいです:
_.factory('myService', function($q, $timeout, $http) {
return {
myMethod: function() {
// return the same promise that $http.get returns
return $http.get('some/url').then(function() {
return 'abc';
});
}
};
})
.controller('myCtrl', function($scope, myService) {
myService.myMethod().then(function(result) {
console.log(result); // 'abc'
return someOtherAsyncFunc(); // for example, say this returns '123'
}).then(function(result) {
console.log(result); // '123'
});
})
_