我如何 return 来自 $q.defer().promise 的集合 Angular?
How do I return a collection from $q.defer().promise in Angular?
Angular v.1.6.1
我正在尝试使用 $q.defer().promise return 一个集合,但我只得到一条记录,而不是从我的 return 编辑的两条记录服务。
模特:
angular.module('app').factory('User',
function() {
/**
* Constructor, with class name
*/
function User(id, firstName, lastName, startDate) {
// Public properties, assigned to the instance ('this')
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.startDate = startDate;
}
/**
* Public method, assigned to prototype
*/
User.prototype.getFullName = function() {
return this.firstName + ' ' + this.lastName;
};
User.apiResponseTransformer = function (responseData) {
if (angular.isArray(responseData)) {
return responseData
.map(User.build)
.filter(Boolean);
}
return User.build(responseData);
}
/**
* Static method, assigned to class
* Instance ('this') is not available in static context
*/
User.build = function(data) {
return new User(
data.Id,
data.FirstName,
data.LastName,
data.StartDate
);
};
/**
* Return the constructor function
*/
return User;
});
服务
(function () {
'use strict';
var serviceId = 'userService';
angular.module('app').factory(serviceId, ['common', '$http', 'config', 'User', userService]);
function userService(common, $http, config, User) {
var $q = common.$q;
var defer = $q.defer();
var service = {
getUsers: getUsers,
getUser: getUser
};
return service;
function getUser(id) {
$http({
method: 'get',
url: config.remoteServiceName + 'users/' + id
}).then(function (response) {
defer.resolve(User.apiResponseTransformer(response.data));
}).then(function (response) {
defer.reject(response);
});
return defer.promise;
}
function getUsers(startDate) {
$http({
method: 'get',
url: config.remoteServiceName +'users/',
params: {
startDate: startDate
}
}).then(function (response) {
var users = [];
angular.forEach(response.data, function (value, key) {
users.push(User.apiResponseTransformer(value));
});
defer.resolve(users);
}).then(function(response) {
defer.reject(response);
});
return defer.promise;
}
}
})();
视图方法
function getUser() {
userService.getUser(1).then(function successCallback(data) {
vm.user = data;
}).catch(function () {
log('An error occured trying to get user...');
});
}
function getUsers() {
userService.getUsers(new Date().toUTCString()).then(function successCallback(data) {
vm.users = data;
}).catch(function () {
log('An error occured trying to get user...');
});
}
在视图中,getUser 调用的功能与预期相同,但 getUsers 仅从服务接收集合中的第一项。我已经验证 response.data 确实包含整个对象集合,并且这些对象被推送到用户数组中。
即使调用 defer.resolve(response.data) 也只会发送集合中的第一项。
感谢任何帮助!
无需从基于承诺的 API 中使用 $q.defer
制造承诺。 (如果对象有一个 .then
方法,它就是一个 promise。)
//ERRONEOUS
function getUser(id) {
$http({
method: 'get',
url: config.remoteServiceName + 'users/' + id
}).then(function (response) {
defer.resolve(User.apiResponseTransformer(response.data));
}).then(function (response) {
defer.reject(response);
});
return defer.promise;
}
由于调用 $http(config)
可以与 .then
方法链接,因此它是一个 returning 承诺。任何可以与 .then
方法链接的 API 调用都是基于承诺的 API。通过注意这一细节,可以确定未知物的性质 API.
//CORRECT
function getUser(id) {
var promise = $http({
method: 'get',
url: config.remoteServiceName + 'users/' + id
})
var nextPromise = promise.then(function (response) {
var value = User.apiResponseTransformer(response.data);
//RETURN value to chain
return value;
}).catch(function (errorResponse) {
//THROW to chain rejection
throw errorResponse;
});
return nextPromise;
};
为清楚起见,已将链分解为它的一部分。 $http 服务调用 return 是一个承诺。 .then
方法调用 return 是一个新的承诺,该承诺解析为 returned 到其响应处理程序的值。新的承诺然后 returned 到封闭函数。
重要的是在每个嵌套级别都有一个 return(或抛出)语句。
用法
getUser(id).then(function(transformedValue) {
console.log(transformedValue);
});
因为调用承诺的 .then
方法 return 是一个新的派生承诺,所以很容易创建承诺链。
可以创建任意长度的链,并且由于一个 promise 可以用另一个 promise 解决(这将进一步推迟其解决方案),因此可以 pause/defer 解决链中任何一点的承诺。这使得实现强大的 APIs.
成为可能
Angular v.1.6.1
我正在尝试使用 $q.defer().promise return 一个集合,但我只得到一条记录,而不是从我的 return 编辑的两条记录服务。
模特:
angular.module('app').factory('User',
function() {
/**
* Constructor, with class name
*/
function User(id, firstName, lastName, startDate) {
// Public properties, assigned to the instance ('this')
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.startDate = startDate;
}
/**
* Public method, assigned to prototype
*/
User.prototype.getFullName = function() {
return this.firstName + ' ' + this.lastName;
};
User.apiResponseTransformer = function (responseData) {
if (angular.isArray(responseData)) {
return responseData
.map(User.build)
.filter(Boolean);
}
return User.build(responseData);
}
/**
* Static method, assigned to class
* Instance ('this') is not available in static context
*/
User.build = function(data) {
return new User(
data.Id,
data.FirstName,
data.LastName,
data.StartDate
);
};
/**
* Return the constructor function
*/
return User;
});
服务
(function () {
'use strict';
var serviceId = 'userService';
angular.module('app').factory(serviceId, ['common', '$http', 'config', 'User', userService]);
function userService(common, $http, config, User) {
var $q = common.$q;
var defer = $q.defer();
var service = {
getUsers: getUsers,
getUser: getUser
};
return service;
function getUser(id) {
$http({
method: 'get',
url: config.remoteServiceName + 'users/' + id
}).then(function (response) {
defer.resolve(User.apiResponseTransformer(response.data));
}).then(function (response) {
defer.reject(response);
});
return defer.promise;
}
function getUsers(startDate) {
$http({
method: 'get',
url: config.remoteServiceName +'users/',
params: {
startDate: startDate
}
}).then(function (response) {
var users = [];
angular.forEach(response.data, function (value, key) {
users.push(User.apiResponseTransformer(value));
});
defer.resolve(users);
}).then(function(response) {
defer.reject(response);
});
return defer.promise;
}
}
})();
视图方法
function getUser() {
userService.getUser(1).then(function successCallback(data) {
vm.user = data;
}).catch(function () {
log('An error occured trying to get user...');
});
}
function getUsers() {
userService.getUsers(new Date().toUTCString()).then(function successCallback(data) {
vm.users = data;
}).catch(function () {
log('An error occured trying to get user...');
});
}
在视图中,getUser 调用的功能与预期相同,但 getUsers 仅从服务接收集合中的第一项。我已经验证 response.data 确实包含整个对象集合,并且这些对象被推送到用户数组中。
即使调用 defer.resolve(response.data) 也只会发送集合中的第一项。
感谢任何帮助!
无需从基于承诺的 API 中使用 $q.defer
制造承诺。 (如果对象有一个 .then
方法,它就是一个 promise。)
//ERRONEOUS function getUser(id) { $http({ method: 'get', url: config.remoteServiceName + 'users/' + id }).then(function (response) { defer.resolve(User.apiResponseTransformer(response.data)); }).then(function (response) { defer.reject(response); }); return defer.promise; }
由于调用 $http(config)
可以与 .then
方法链接,因此它是一个 returning 承诺。任何可以与 .then
方法链接的 API 调用都是基于承诺的 API。通过注意这一细节,可以确定未知物的性质 API.
//CORRECT
function getUser(id) {
var promise = $http({
method: 'get',
url: config.remoteServiceName + 'users/' + id
})
var nextPromise = promise.then(function (response) {
var value = User.apiResponseTransformer(response.data);
//RETURN value to chain
return value;
}).catch(function (errorResponse) {
//THROW to chain rejection
throw errorResponse;
});
return nextPromise;
};
为清楚起见,已将链分解为它的一部分。 $http 服务调用 return 是一个承诺。 .then
方法调用 return 是一个新的承诺,该承诺解析为 returned 到其响应处理程序的值。新的承诺然后 returned 到封闭函数。
重要的是在每个嵌套级别都有一个 return(或抛出)语句。
用法
getUser(id).then(function(transformedValue) {
console.log(transformedValue);
});
因为调用承诺的 .then
方法 return 是一个新的派生承诺,所以很容易创建承诺链。
可以创建任意长度的链,并且由于一个 promise 可以用另一个 promise 解决(这将进一步推迟其解决方案),因此可以 pause/defer 解决链中任何一点的承诺。这使得实现强大的 APIs.
成为可能