javascript - 调用服务函数 : Not Populating Scope On First Execution

标签 javascript angularjs

我正在重构一些 AngularJS 代码,以使 Controller 更精简,并将一些逻辑移至服务中。

旧代码这可以正常工作。

在 Controller 中...

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;
    };

重构代码未按预期工作

在 Controller 中...

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 已正确填充。

为什么第一次执行不能正常工作?我做错了什么?

最佳答案

在你的 Controller 中

$scope.firmList = firmService.appendFirmListByDate(firmSearchRequest);

这里的函数 firmService.appendFirmListByDate() 是一个简单的函数,将同步运行,因此值将立即返回,因此在这种情况下返回的值是名为 firmList 的空数组强>

所以问题就出现了,为什么当您第二次单击该按钮时会得到正确的列表。

  • 当您第二次单击该按钮时,由于第一次运行的 Promise,数组中的值 varfirmList = [] 被插入

    this.getFirms(firmSearchRequest).then(function(response) {          
        firmList = firmList.concat(response.data);
    });
    
  • 当您第二次单击该按钮时,该函数仍然同步运行,并且您获得了第一步中填充的值。

注意 - 因此每次您获得的值都是由上一步中的 promise 填充的。

重点

  • 你不能以这种方式重构你的代码

  • 制作一个瘦 Controller 并不意味着取消它的 promise 。这意味着业务逻辑不应该存在。所以你的 promise 应该在服务内部,它应该返回一个 promise 给 Controller ,数据操作等应该在服务内部完成

返回服务 promise

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);
            });
        }

    });
};

关于javascript - 调用服务函数 : Not Populating Scope On First Execution,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39836537/

相关文章:

javascript - 使用 jquery 提取 src 并粘贴到 html 链接之前

javascript - 将文件切片读取为字节并发送到服务器?

angularjs - 范围内的范围。 AngularJS

AngularJS:如何测试将焦点放在元素上的指令?

javascript - 获取在 Angular 范围内显示的新名称

javascript - 在 Angularjs 应用程序中使用 AND 操作过滤基于 ng 重复的多个属性

javascript - JavaScript 中的 setTimeout 冲突

javascript - knockout 点击事件防止子值改变

javascript - Angular/JS : How do I pass a scope variable to a javascript function?

javascript - 使用 javascript 在 6 x 6 的表格中生成 div