我正在重构一些angularjs代码以使控制器更精简并将一些逻辑移动到服务中。
旧代码这样就行了。
在控制器......
var firmSearchRequest = {
type : "ByDate",
startDate : $scope.startDate,
endDate : $scope.endDate
};
firmService.getFirms(firmSearchRequest).then(function(response) {
firmService.appendFirmList(response.data);
$scope.firmList = firmService.getFirmList();
});
在服务中......
var firmList = [];
this.getFirms = function(firmSearchRequest) {
return httpService.putForResponse('firms/search', firmSearchRequest);
};
this.appendFirmList = function(newfirmList){
firmList = firmList.concat(newfirmList);
}
this.getFirmList = function() {
return firmList;
};
重构代码无法按预期工作
在控制器......
var firmSearchRequest = {
type : "ByDate",
startDate : $scope.startDate,
endDate : $scope.endDate
};
$scope.firmList = firmService.appendFirmListByDate(firmSearchRequest);
在服务中......
var firmList = [];
this.appendFirmListByDate = function(firmSearchRequest){
this.getFirms(firmSearchRequest).then(function(response) {
firmList = firmList.concat(response.data);
});
return firmList;
};
this.getFirms = function(firmSearchRequest) {
return httpService.putForResponse('firms/search', firmSearchRequest);
};
意外行为
对于重构代码,当我单击执行上述代码的按钮时,我没有收到控制台错误,但$scope.firmList
为空。当我再次单击该按钮进行第二次执行时,$scope.firmList
被正确填充。
为什么第一次执行无法正常工作?我做错了什么?
答案 0 :(得分:1)
在您的控制器中
$scope.firmList = firmService.appendFirmListByDate(firmSearchRequest);
这里函数 firmService.appendFirmListByDate()是一个简单的函数,它会同步运行,所以会立即返回值,所以在这种情况下返回的值是名为 firmList的空数组强>
所以问题就出现了为什么当你第二次点击按钮时得到正确的列表。
当您第二次单击该按钮时,插入了数组 var firmList = [] 中的值,因为第一次运行的承诺是
this.getFirms(firmSearchRequest).then(function(response) {
firmList = firmList.concat(response.data);
});
当您第二次单击该按钮时,该功能仍然会同步运行,并且您获得了第一步填充的值。
注意 - 所以每当你获得一个由最后一步中的承诺填充的值时。
重点
您无法以这种方式重构代码
制作一个瘦控制器并不意味着删除它的承诺。这意味着业务逻辑不应该存在。所以你的承诺应该是内部服务,应该向控制器返回一个承诺,数据操作等应该在服务中完成
从服务中退回承诺
this.appendFirmListByDate = function(firmSearchRequest){
return new Promise(function(resolve,reject){
//if firmList contains data then just return it
if(firmList.length!==0){
resolve(firmList);
}else{
this.getFirms(firmSearchRequest).then(function(response) {
firmList = firmList.concat(response.data);
resolve(firmList);
}).catch(function(error){
reject(error);
});
}
});
};
答案 1 :(得分:0)
你是不是在尝试返回firmList之前(技术上无论是否)承诺完成了?
您应该将回报置于承诺内,或者可以返回承诺。
答案 2 :(得分:0)
您可以使用callaback
功能
<强>服务强>
this.appendFirmListByDate = function(firmSearchRequest, fct){
this.getFirms(firmSearchRequest).then(function(response) {
fct(firmList.concat(response.data);)
});
};
<强>控制器强>
firmService.appendFirmListByDate(firmSearchRequest, function(result){
$scope.firmList = result;
});