2016-11-17 1 views
0

В течение последних двух дней я читал о обещаниях, обратных вызовах и генераторах, пытаясь выяснить, как я могу установить значение из асинхронной функции что я могу использовать в объекте $ scope.

Я не могу получить обещание решить тогда var, он просто возвращает обещание, а не значение, которое оно должно делать из того, что я понимаю. Это где я думал, может быть, генератор может помочь?

Итак, как я поставил var из функции асинхронной, так что я могу использовать эту var в объекте $scope.options_scn_cst

Это специально для nvd3, как то, что я пытаюсь сделать, это перебрать результаты функции loopback Rpt_scn_cost_v, чтобы найти максимальное значение, а затем установите это как максимальное значение по оси Y в yDomain: [min, max] для nvd3.

Мой код прямо сейчас выглядит следующим образом:

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> 

Я попробовал этот путь, а также с помощью $ д, но это возвращает обещание, а не стоимость тоже ...

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 = {...} 
}) 

Это, конечно, требует, чтобы <nvd3> директивы использовать часы над его options связыванием обнаружить, что переменное есть если он определен.

Если это не так, и 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

спасибо, что так много! это сработало! – 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); 
}); 
Смежные вопросы