$ q.all没有按预期工作

时间:2017-02-17 13:13:55

标签: javascript angularjs angular-promise

如果有两个API调用尚未准备好结果,我想显示一个加载div。

所以结果突然没有跳到视图中导致它闪烁。

我的观点看起来像这样:

<div ng-show="vm.loading" class="table-overlay table-overlay-loading">
    <div class="table-overlay-content">
        <div class="table-overlay-message">Loading&hellip;</div>
    </div>
</div>
<div ng-show="vm.loadError" class="table-overlay table-overlay-error">
    <div class="table-overlay-content">
        <div class="table-overlay-message"><i class="icon-error-indicator"></i>
            Error encountered. Please try again.
        </div>
    </div>
</div>
<div class="inner" ng-show="!vm.loading && !vm.loadError">
    <div class="info-panel">
        <h3>Current Pricing</h3>
        <p>
            Billing Period:
            <br>
            <em>{{vm.invoiceCoverageStartDate}} to {{vm.invoiceCoverageEndDate}}</em>
            <br>
            <big><b>${{vm.invoiceTotal}}</b>/month</big>
            <br>
            <a href=""><small>(See Details)</small></a>
        </p>
    </div>

填充interpolated values的方法如下:

       vm.getCurrentPricingDetails = function(){
            HttpWrapper.send(url1, {"operation":'GET'})
            .then(function(result){
                console.log("Current Pricing Response: ", result);
                vm.invoiceCoverageStartDate = $filter('date')(result.invoice.coverageStartDate, "dd/MM/yyyy");
                vm.invoiceCoverageEndDate = $filter('date')(result.invoice.coverageEndDate, "dd/MM/yyyy");
                vm.invoiceTotal = result.invoice.invoiceTotal;
            }, function(error) {
                console.log("Error: Could not fetch current pricing details", error);
            });
        }


        vm.getProjectedPricing = function(){
            $timeout(function(){
                var selectedPricingMappingObj = dataStoreService.getItems('server');
                selectedPricingMappingObj.forEach(function(item){
                    vm.totalProjectedPricingSum += parseFloat(item.selectedMapping.cost);
                });
                vm.totalProjectedPricingSum = vm.totalProjectedPricingSum.toFixed(2);
            },1000);                                  
        }

但在我的组件中$onInit method I tried to resolve the same using promise.

      vm.$onInit = function() {                
            vm.loading = true;
            vm.loadError = false;
            var currentPricingDetails = vm.getCurrentPricingDetails();
            var projectedPricingDetails = vm.getProjectedPricing();

            $q.all([currentPricingDetails,projectedPricingDetails]).then(function(results) {
                debugger;
                vm.loading = false;
            }, function(error){
                debugger;
                vm.loading = false;
                vm.loadError = true;
            });

但屏幕仍然闪烁,loading div没有显示。

我希望loading div显示,除非两个方法调用未完成结果。

如何实现?

我做错了什么?

2 个答案:

答案 0 :(得分:4)

vm.getCurrentPricingDetails()和vm.getProjectedPricing()不返回任何内容。你的行

$q.all([currentPricingDetails,projectedPricingDetails])

真的只是

$q.all([undefined, undefined])

$ q.all期望一系列承诺。 $ timeout在完成后返回一个承诺。看起来您的HttpWrapper也会回复承诺。所以我认为您需要做的就是为代码添加回报:

return HttpWrapper.send(url1, {"operation":'GET'})

return $timeout(function(){

答案 1 :(得分:2)

vm.getCurrentPricingDetails和vm.getProjectedPricing没有返回promises,因此$ q.all没有机会知道它们何时完成

    m.getCurrentPricingDetails = function(){
        var defer = $q.defer();
        HttpWrapper.send(url1, {"operation":'GET'})
        .then(function(result){
            console.log("Current Pricing Response: ", result);
            vm.invoiceCoverageStartDate = $filter('date')(result.invoice.coverageStartDate, "dd/MM/yyyy");
            vm.invoiceCoverageEndDate = $filter('date')(result.invoice.coverageEndDate, "dd/MM/yyyy");
            vm.invoiceTotal = result.invoice.invoiceTotal;
           defer.resolve();
        }, function(error) {
            console.log("Error: Could not fetch current pricing details", error);
            defer.reject();
        });
        return defer.promise;
    }


    vm.getProjectedPricing = function(){
        var defer = $q.defer();
        $timeout(function(){
            var selectedPricingMappingObj = dataStoreService.getItems('server');
            selectedPricingMappingObj.forEach(function(item){
                vm.totalProjectedPricingSum += parseFloat(item.selectedMapping.cost);
            });
            vm.totalProjectedPricingSum = vm.totalProjectedPricingSum.toFixed(2);
            defer.resolve();
        },1000);   
        return defer.promise;                               
    }