2016-11-17 46 views
0

在過去的兩天裏,我一直在閱讀有關承諾,回調和生成器的嘗試,以瞭解如何從異步函數中設置值我可以在$ scope對象中使用它。

我不能得到承諾,然後解決var,它只是返回承諾,而不是價值,這是它應該做的,據我所知。這是我認爲也許發電機可能會有所幫助的地方?

那麼,如何從一個異步功能設置var,這樣我可以在對象使用var$scope.options_scn_cst

這是專門爲nvd3,因爲我想要做的,是要遍歷來自回送功能Rpt_scn_cost_v的結果找到最大值,然後將其設置爲用於nvd3的yDomain: [min, max]中Y軸的最大值。

我的代碼現在看起來是這樣的:

function maxYvalue2() { 
    return Rpt_scn_cost_v.find({filter: { where: {scenario_id: $stateParams.id}}}).$promise.then(function(response){ 
     var maxYvalue = 0; 
     var currMaxYvalue = 0; 
     for (var i=0;i<response.length;i++) { 
      var currMaxYvalue = parseFloat(response[i].cur_cost) + parseFloat(response[i].tgt_cost); 
      if (currMaxYvalue > maxYvalue) { 
       maxYvalue = currMaxYvalue; 
      }; 
     } 
     return maxYvalue; 
     console.log("yVal: ", maxYvalue) 
    }); 
}; 

var mxY = 100000 // <======== when I set it to this maxYvalue2(), it resolves in a promise 

console.log('var', mxY) 




$scope.options_scn_cst = { 
     chart: { 
      type: 'lineChart', 
      height: 450, 
      margin : { 
       top: 20, 
       right: 20, 
       bottom: 40, 
       left: 55 
      }, 
      x: function(d){ return d.x; }, 
      y: function(d){ return d.y; }, 
      useInteractiveGuideline: true, 
      dispatch: { 
       stateChange: function(e){ console.log("stateChange"); }, 
       changeState: function(e){ console.log("changeState"); }, 
       tooltipShow: function(e){ console.log("tooltipShow"); }, 
       tooltipHide: function(e){ console.log("tooltipHide"); } 
      }, 
      xAxis: { 
       axisLabel: '', 
       tickFormat: function(d) { return d3.time.format('%b %y')(new Date(d)); } 
      }, 
      yDomain: [0, mxY], // <============ I then set mxY here in the $scope object 
      yAxis: { 
       axisLabel: '$/month', 
       tickFormat: function(d){ 
        return d3.format('$,.0f')(d); 
       }, 
       axisLabelDistance: -10 
      }, 
      callback: function(chart){} 
     }, 
     title: { 
      enable: true, 
      text: 'Scenario Costs Over Time' 
     }, 
     subtitle: { 
      enable: false, 
      text: 'Put your Subtitle here.', 
      css: { 
       'text-align': 'center', 
       'margin': '10px 13px 0px 7px' 
      } 
     }, 
     caption: { 
      enable: false, 
      html: 'Put your Caption Here.', 
      css: { 
       'text-align': 'justify', 
       'margin': '10px 13px 0px 7px' 
      } 
     } 
    }; 

,然後我把這樣的$範圍對象,然後:

<nvd3 data="data_scn_cst" options="options_scn_cst"></nvd3> 

我想這樣也使用$ Q,但它回覆承諾,而不是價值太...

function maxYvalue2() { 

    var deferred = $q.defer(); 

    Rpt_scn_cost_v.find({filter: { where: {scenario_id: $stateParams.id}}}).$promise.then(function(response){ 
     var maxYvalue = 0; 
     var currMaxYvalue = 0; 
     for (var i=0;i<response.length;i++) { 
      var currMaxYvalue = parseFloat(response[i].cur_cost) + parseFloat(response[i].tgt_cost); 
      if (currMaxYvalue > maxYvalue) { 
       maxYvalue = currMaxYvalue; 
      }; 
     } 
     deferred.resolve(maxYvalue) 
     console.log("yVal: ", maxYvalue) 
    }); 

    return deferred.promise 
}; 

var mxY = maxYvalue2() // <======== when I set it to this maxYvalue2(), it resolves in a promise 

console.log('var', mxY) 

回答

1

因爲你的代碼在本質上是異步的,你永遠不會讓它進入你的變種同步,無論方法,你試試。

你有幾種方法可以解決這個問題。一種選擇是等待承諾解決(使用其方法then),然後才能創建$scope.options_scn_cst對象。

maxYvalue2().then(function(maxYvalue) { 
    // Now that we know maxYvalue, define the scope variable 
    $scope.options_scn_cst = {...} 
}) 

當然,這需要您使用在其options結合手錶<nvd3>指令,以檢測該變量。有一次它被定義。

如果是沒有的情況下和nvd3是你的指令,你可以使用$scope.$watch('options', function() {...})

如果情況並非如此,在nvd3指令不是你的,你可以圍繞着它在一些ng-if元素只顯示它曾經options_scn_cst存在:

<nvd3 ng-if="options_scn_cst" data="data_scn_cst" options="options_scn_cst"></nvd3> 
+0

謝謝sooo多!工作! – user2061886

+0

這裏也有一個問題......我將如何使用生成器代替或承諾? – user2061886

2

Rpt_scn_cost_v.find返回一個承諾,我假設。這可讓您鏈中的承諾,並將結果:

function maxYvalue2() { 
    return Rpt_scn_cost_v.find({filter: { where: {scenario_id: $stateParams.id}}}).then(function(response){ 
     var maxYvalue = 0; 
     var currMaxYvalue = 0; 
     for (var i=0;i<response.length;i++) { 
      var currMaxYvalue = parseFloat(response[i].cur_cost) + parseFloat(response[i].tgt_cost); 
      if (currMaxYvalue > maxYvalue) { 
       maxYvalue = currMaxYvalue; 
      } 
     } 
     return maxYvalue; 
    }); 
} 

使用由:

maxYvalue2().then(function(maxYvalue) { 
    console.log('maxYvalue=', maxYvalue); 
}); 
相關問題