调用服务函数:第一次执行时没有填充作用域
Call To Service Function: Not Populating Scope On First Execution
我正在重构一些angularjs代码,以使控制器更精简,并将一些逻辑移动到服务中。
旧代码 This works OK.
在控制器…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
被正确填充。
为什么第一次执行不能正常工作?我做错了什么?
在你的控制器
$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);
});
}
});
};
不是你试图返回firmList之前(技术上无论是否)的承诺完成?
你应该把return放在promise里面,或者返回promise。
可以使用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;
});
相关文章:
- 监视函数从服务返回不起作用,但作用域函数起作用
- 将作用域存储在JSON中
- 从控制器继承了隔离的作用域以生成可重用的指令
- 从ng模板访问作用域
- 调用私有作用域
- 对父作用域的指令更新延迟了一步
- 正在$rootScope上达到控制器作用域$在内部控制器上
- 两个指令创建新的继承的和隔离的作用域-元素得到哪个
- 这两个关于 JavaScript 作用域链的例子有什么区别?
- 在具有命名作用域的自定义Polymer元素中隐藏表行
- AngularJS指令隔离作用域
- Angularjs:修改js中的作用域,稍后在页面中使用
- 访问多个指令的隔离作用域
- angularjs用现有控制器中的REST服务填充作用域变量
- Angularjs ng-show等待作用域的填充
- 在Angularjs中使用资源填充作用域属性
- 调用服务函数:第一次执行时没有填充作用域
- 没有使用Angular作用域填充Jquery对话框
- 如何用http响应填充作用域
- Angularjs用不同作用域的inng -repeat填充下拉列表