2015-09-10 2 views
0

Я создаю угловую директиву для отображения в реальном времени графика, вот код, который возвращает все, включая link:function() { } внутри директивы.Статический ответ РАБОТАЕТ! В то время как Asynchronous не работает

Вот код для статической директивы , который отлично работает

angular.module('app').directive("flotChartRealtime", [ 
    function() { 
     return { 
      restrict: "AE", 
      link: function(scope, ele) { 
       var realTimedata, 
        realTimedata2, 
        totalPoints, 
        getSeriesObj, 
        getRandomData, 
        getRandomData2, 
        updateInterval, 
        plot, 
        update; 
       return realTimedata = [], 
        realTimedata2 = [], 
        totalPoints = 100, 
        getSeriesObj = function() { 
         return [ 
          { 
           data: getRandomData(), 
           lines: { 
            show: true, 
            lineWidth: 1, 
            fill: true, 
            fillColor: { 
             colors: [ 
              { 
               opacity: 0 
              }, { 
               opacity: 1 
              } 
             ] 
            }, 
            steps: false 
           }, 
           shadowSize: 0 
          }, { 
           data: getRandomData2(), 
           lines: { 
            lineWidth: 0, 
            fill: true, 
            fillColor: { 
             colors: [ 
              { 
               opacity: .5 
              }, { 
               opacity: 1 
              } 
             ] 
            }, 
            steps: false 
           }, 
           shadowSize: 0 
          } 
         ]; 
        }, 
        getRandomData = function() { 
         if (realTimedata.length > 0) 
          realTimedata = realTimedata.slice(1); 

         // Do a random walk 
         //console.log(realTimedata); 
         while (realTimedata.length < totalPoints) { 

          var prev = realTimedata.length > 0 ? realTimedata[realTimedata.length - 1] : 50, 
           y = prev + Math.random() * 10 - 5; 

          if (y < 0) { 
           y = 0; 
          } else if (y > 100) { 
           y = 100; 
          } 
          realTimedata.push(y); 
         } 

         // Zip the generated y values with the x values 

         var res = []; 
         for (var i = 0; i < realTimedata.length; ++i) { 
          res.push([i, realTimedata[i]]); 
         } 

         return res; 
        }, 
        getRandomData2 = function() { 
         if (realTimedata2.length > 0) 
          realTimedata2 = realTimedata2.slice(1); 

         // Do a random walk 

         while (realTimedata2.length < totalPoints) { 

          var prev = realTimedata2.length > 0 ? realTimedata[realTimedata2.length] : 50, 
           y = prev - 25; 

          if (y < 0) { 
           y = 0; 
          } else if (y > 100) { 
           y = 100; 
          } 
          realTimedata2.push(y); 
         } 


         var res = []; 
         for (var i = 0; i < realTimedata2.length; ++i) { 
          res.push([i, realTimedata2[i]]); 
         } 

         return res; 
        }, 

        // Set up the control widget 
        updateInterval = 500, 
        plot = $.plot(ele[0], getSeriesObj(), { 
         yaxis: { 
          color: '#f3f3f3', 
          min: 0, 
          max: 100, 
          tickFormatter: function(val, axis) { 
           return ""; 
          } 
         }, 
         xaxis: { 
          color: '#f3f3f3', 
          min: 0, 
          max: 100, 
          tickFormatter: function(val, axis) { 
           return ""; 
          } 
         }, 
         grid: { 
          hoverable: true, 
          clickable: false, 
          borderWidth: 0, 
          aboveData: false 
         }, 
         colors: ['#eee', scope.settings.color.themeprimary], 
        }), 
        update = function() { 
         plot.setData(getSeriesObj()); // getting .data filled here perfectly 
         plot.draw(); 
         setTimeout(update, updateInterval); 
        }, 
        update(); 
      } 
     }; 
    } 
]); 

Мой код с запросом HTTP который не работает

getSeriesObj = function() { 
    return [{ 
     data: getRandomData(function(res) { 
      console.log(res) // getting array result here from http call but not returning to data: 
      return res; 
     }), 
     lines: { 
      show: true, 
      lineWidth: 1, 
      fill: true, 
      fillColor: { 
       colors: [{ 
        opacity: 0 
       }, { 
        opacity: 1 
       }] 
      }, 
      steps: false 
     }, 
     shadowSize: 0 
    }, { 
     data: getRandomData2(function (res) { 
      return res; 
     }), 
     lines: { 
      lineWidth: 0, 
      fill: true, 
      fillColor: { 
       colors: [{ 
        opacity: .5 
       }, { 
        opacity: 1 
       }] 
      }, 
      steps: false 
     }, 
     shadowSize: 0 
    }]; 
}, 
getRandomData = function (callback) { 
    var authToken = window.localStorage.getItem('token'); 
    var url = $rootScope.apiPath + 'Elasticsearch/countget?token=' + authToken; 
    var res = []; 
    $http.get(url).then(function (result) { 
     realTimedata = result.data; 
     if (realTimedata.length > 0) 
     //result = [10,22,33,11,32,88,77,66,21,90,92,98,99.9,88.8,76,66,56,88]; 
     for (var i = 0; i < realTimedata.length; ++i) { 
      var y = realTimedata[i] + Math.random() * 10 - 5; 
      if (y < 0) { 
       y = 0; 
      } else if (y > 100) { 
       y = 100; 
      } 
      res.push([i, y]); 
     } 
     callback(res); 
    }); 
}, 

Проблема:

Когда я пытаюсь следующим кодом:

update = function() { 
    //console.log(getSeriesObj()); 
    plot.setData(getSeriesObj()); // .data property gets undefined 
    plot.draw(); 
    setTimeout(update, updateInterval); 
} 

функция getSeriesObj() возврата массива объекта, который возвращает data свойства undefined, что может быть причиной?

Как я могу решить эту проблему?

Примечание: Это сильно отличается от this question.

+0

является 'getRandomData2' таким же, как' getRandomData'?потому что если так, то 'getRandomData2' может ничего не вернуть из-за задачи async, поэтому' data' не определено – Hacketo

+0

Возможный дубликат [Как вернуть ответ от асинхронного вызова?] (http://stackoverflow.com/questions/14220321/ How-to-return-the-response-from-a-асинхронный вызов) – Hacketo

+0

'data: getRandomData2 (функция (res) {return res;})' this execute 'getRandomData2', что возвращает' getRandomData2'? 'undefined'. Ваша проблема такая же, как в связи с сообщением, которое я связал. Вы не можете вернуть ответ от асинхронного вызова – Hacketo

ответ

2

Когда это сделать

data: getRandomData(function(res) { 
    return res; 
}); 

присваивается RValue из getRandomData в data.

Как указано в вашем сообщении, getRandomData теперь не имеет инструкции return, поэтому возвратите undefined.

Основная проблема здесь состоит в том, что вы ожидаете, что plot.setData(getSeriesObj()); работа synchronously

Шаги

  1. получить данные для заполнения plot
  2. установить данные в plot
  3. нарисовать
  4. обновить значения снова

Теперь, когда HTTP-запрос работает async, вы не можете ожидать получить значение от getSeriesObj(). Вы должны думать, что getSeriesObj работы теперь асинхронном, так что вы можете работать только с обратным вызовом, которая будет срабатывать, когда ресурс готов к использованию

поэтому метод обновления стало

update = function() { 
    var updateTime = +new Date; 
    getSeriesObj(function(res){ // execute that stuff when ready 
     plot.setData(res); 
     plot.draw(); 
     setTimeout(update, Math.max(10, updateInterval - (+new Date - updateTime))); 
    }); 
} 

и getSeriesObj

getSeriesObj = function (callback) { 
    getRandomData(function(res) { 
     getRandomData2(function(res2){ 
      var data = [{ 
       data: res, 
       lines: { 
        show: true, 
        lineWidth: 1, 
        fill: true, 
        fillColor: { 
         colors: [{ 
          opacity: 0 
         }, { 
          opacity: 1 
         }] 
        }, 
        steps: false 
       }, 
       shadowSize: 0 
      }, { 
       data: res2, 
       lines: { 
        lineWidth: 0, 
        fill: true, 
        fillColor: { 
         colors: [{ 
          opacity: .5 
         }, { 
          opacity: 1 
         }] 
        }, 
        steps: false 
       }, 
       shadowSize: 0 
      }]; 
      callback(data); // now the ressource obj is now ready to be used 
     }); 
    }); 
} 
+0

так как обратный вызов не входит в область, где вы написали, это порождает ошибку 'callback is not defined'! –

+0

необходимо определить как параметр 'getSeriesObj' так в той же области, что и callback (data)' call – Hacketo

+0

Большое спасибо Hacketo! Он отлично работает! Ура! –

Смежные вопросы