如何使用angularjs延迟加载谷歌jsapi图表

How to lazy load google jsapi charts with angularjs?

本文关键字:jsapi 图表 谷歌 延迟加载 何使用 angularjs      更新时间:2023-09-26

我有一个单页应用程序,但有不同的选项卡。只对于一个选项卡,我想显示一个google charts.我不想直接包含和加载图表 js 文件jsapi,但只有在访问特定选项卡时。

因此,我必须动态添加js,如下所示:

var script = document.createElement('script');
script.src = '//http://www.google.com/jsapi?ext.js';
document.body.appendChild(script);

问题:如何检测 js 何时完全加载,以便我可以继续如下?

if (whenJspaiLoaded()) {
    google.load('visualization', '1', {packages: ['corechart']});
    google.setOnLoadCallback(drawChart); //my custom function
}
这是我

的实现

    <style>
    .preloader {
        height:350px; background:url(images/719.gif) left no-repeat;
    }
    </style>
    <div id="columnchart_material"><div class="preloader">&nbsp;</div></div>
<script type="text/javascript"
          src="https://www.google.com/jsapi?autoload={
            'modules':[{
              'name':'visualization',
              'version':'1',
              'packages':['corechart']
            }]
          }">
</script>
    <script>
google.setOnLoadCallback(drawChart);
      function drawChart() {
    var chart = new google.visualization.LineChart(document.getElementById('columnchart_material'));
                options.title='English'
                options.series[1].lineWidth = 0;
            chart.draw(data,options );
}
    </script>

代码笔 点击这里

试试 Angular Google Chart。它抽象了指令背后的图表管理,因此您只需向它传递一个包含数据、选项和图表类型的对象,其余的由它完成。 它不会添加脚本标记,直到它第一次加载指令,或者您请求库加载时返回的承诺。 如果你真的想抑制库加载,你需要确保指令元素在你实际需要它之前不会在后台加载。因此,请使用 ng-if 而不是 ng-show 或将其放在不同的路由视图中。

由于到目前为止网上似乎没有可行的解决方案,我希望这将在未来对某人有所帮助。关键概念是延迟js文件加载和图表组件初始化,并带有callback

加载 js 文件的服务:

app.service('gchart', ['$window', '$q', '$rootScope', function ($window, $q, $rootScope) {
      var deferred = $q.defer();
      //run when the jsapi is loaded
      $window.callback = function () {
            $window.google.load('visualization','1',{
                packages: ['corechart'],
                callback: function() {
                    //again having a callback to wait for the visualization to load
                    $rootScope.$apply(function() {
                        deferred.resolve();
                    });
                }
            });
      }
      // dynamically adding the js file on page access
      var script = document.createElement('script');
      script.src = '//www.google.com/jsapi?callback=callback';
      document.body.appendChild(script);
      return deferred.promise;
}]);

作为指令的用法:

app.directive(.., ['gchart', function(.., gchart) {
   return {
      //...
      link: function(scope, elm, attr) {
          scope.init = function() {
              var viz = new google.visualization.arrayToDataTable(data);
              //add options, linechart, draw, whatever
          };
          // delay the creation until jsapi files loaded
          loadGoogleChartAPI.then(function () {
              scope.init();
          }, function () {
              //ignore
          });           
       }
   }
}

带回调的异步函数:

function async(u, c) {
  var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
  o.src = '//' + u;
  if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
  s.parentNode.insertBefore(o, s);
}

用法:

async('www.google.com/jsapi?ext.js', function() {
    google.load('visualization', '1', {packages: ['corechart']});
    google.setOnLoadCallback(drawChart);
});

从 : https://stackoverflow.com/a/12821561/3279156