2016-04-21 6 views
1

Ich habe eine einzelne Seite Anwendung, aber mit verschiedenen Tabs. Nur für eine Registerkarte möchte ich eine google charts zeigen. Ich möchte die Diagramme js-Datei jsapi nicht direkt einbeziehen und laden, sondern nur, wenn auf die spezifische Registerkarte zugegriffen wird.Wie kann ich Google jsapi Charts mit angularjs laden?

Deshalb muss ich die js hinzufügen wie folgt dynamisch:

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

Problem: Wie kann ich erkennen, wenn die js vollständig geladen ist, so dass ich wie folgt fortgesetzt werden kann?

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

Antwort

0

Wie es scheint, bisher im Netz keine funktionierende Lösung zu sein Ich hoffe, das wird jemandem in fu helfen ture. Das Schlüsselkonzept besteht darin, sowohl das Laden der Datei js als auch die Initialisierung der Kartenkomponenten mit einer callback zu verzögern.

der Dienst die js Dateien zu laden:

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; 
}]); 

Verwendung als Richtlinie:

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 
      });   
     } 
    } 
} 
-1

Async-Funktion mit Rückruf:

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); 
} 

Verbrauch:

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

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

+0

ist 'addEventListener' browserunabhängig? IE, Chrome, FF, Opera? – membersound

+0

@Membersound für IE können Sie dies überprüfen, http://Stackoverflow.com/a/6927800/3279156 mehr über die Kompatibilitätsprüfung in: http://caniuse.com/#feat=addeventlistener – sreeramu

2

Hier ist meine Implementierung

<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> 

Codepen click here

+0

Wo laden Sie die 'jsapi' und das 'corechart' Modul initialisieren? Wo ist der Lazy Loading Teil? – membersound

1

Geben Sie Angular Google Chart einen Versuch. Es abstrahiert die Diagrammverwaltung hinter einer Direktive, so dass Sie einfach ein Objekt mit den Daten, Optionen und dem Diagrammtyp übergeben und den Rest erledigt. Es fügt das Skript-Tag erst beim ersten Laden der Anweisung hinzu, oder Sie fragen nach dem Versprechen, das beim Laden der Bibliothek zurückgegeben wird. Wenn Sie das Laden von Bibliotheken wirklich unterdrücken möchten, müssen Sie sicherstellen, dass das Direktivenelement nicht im Hintergrund geladen wird, bis Sie es tatsächlich benötigen. Verwenden Sie also ng-if anstelle von ng-show oder fügen Sie es in eine andere geroutete Ansicht ein.

+0

Während dies funktionieren könnte, ist es eine zusätzliche Abhängigkeit. Niemand weiß, wie lange es in Zukunft unterstützt wird, daher möchte ich mich nicht darauf verlassen. – membersound

+1

Verständlich, ich hatte in letzter Zeit nicht mehr so ​​viel Zeit, um damit zu arbeiten, und erst in der letzten Woche haben sich andere Leute dafür interessiert, Wartungsanforderungen mitzutragen, bei denen ich keine Zeit hatte, Updates zu schreiben. Ich bin immer noch hier, ich versuche immer so schnell wie möglich GitHub-Fragen und Fragen zu Gitter zu beantworten. – nbering