Angular Js和google api client.js(gapi)

我花了一天的时间才做到这一点,所以我觉得我的经验可能对某人有用。 也许其他一些人会发现改善。

所以我两天前开始使用angularJS。 我希望它可以与Google Cloud Endpoints一起使用来创build后端界面。 这给我带来了麻烦。

gapi的javascript客户端来自asynchronous加载,所以angular度初始化将崩溃gapi未定义。

所以当gapi被初始化时,你需要引导angular度:

  1. 删除ng-app =“myApp”
  2. 添加<script src="https://apis.google.com/js/client.js?onload=googleOnLoadCallback"></script>
  3. 添加callback:

     function googleOnLoadCallback(){ var apisToLoad = 1; // must match number of calls to gapi.client.load() var gCallback = function() { if (--apisToLoad == 0) { //Manual bootstraping of the application var $injector = angular.bootstrap(document, ['myApp']); console.log('Angular bootstrap complete ' + gapi); }; }; gapi.client.load('helloWorld', 'v1', gCallback, '//' + window.location.host + '/_ah/api'); } 

感觉不错,但是打个电话怎么样?

所以这里是控制器:

 angular.module('myApp.controllers', []). .controller('MyCtrl', ['$scope' ,'helloWorldService', function($scope,greetingsService) { helloWorldService.loadData($scope); }]); 

这里是服务:

 angular.module('myApp.services', []) service('helloWorldService', [function() { this.loadData = function($scope) { //Async call to google service gapi.client.helloWorld.greetings.listGreeting().execute( function(resp) { if (!resp.code) { console.debug(resp); $scope.greetings = resp.items; // Because it's a callback, // we need to notify angular of the data refresh... $scope.$apply(); } }); }; }]); 

神奇的是你的页面更新感谢angular度。

随时标记我出错的地方。

在进行服务器请求之前/之前让Angular加载是非常有效的,而不是引导或设置超时。 我遵循了AngularJS + Cloud Endpoints:build立现代Web应用程序的一个方法 ,其中描述了如下的build议。

像往常一样保持你的ng-app指令(没有引导)

 <html ng-app="myApp"> <head> <script src="angular.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <script src="https://apis.google.com/js/client.js?onload=init"></script> </head> <body ng-show="backendReady"> 

在JS的任何地方为GAPIcallback函数创build一个全局variables

 var app = angular.module('myApp', []); var init = function() { window.initGapi(); } app.controller('MainController', function($scope, $window, gapiService) { var postInitiation = function() { // load all your assets } $window.initGapi = function() { gapiService.initGapi(postInitiation); } }); app.service('gapiService', function() { this.initGapi = function(postInitiation) { gapi.client.load('helloWorld', 'v1', postInitiation, restURL); } }); 

从上面的链接:

之所以不想在第一个init()方法中执行初始化,是因为您可以在AngularJS世界中尽可能多地放置代码,例如控制器,服务和指令。 因此,您可以利用AngularJS的全部function,并进行所有的unit testing,集成testing等等。

这可能看起来像是一个迂回的做事方式,但它优化了速度,可testing性关注点分离。

好post,谢谢! 这种方法为我工作。 这可能与代码在您的index.html文件中出现的顺序有关。 在我按照这个顺序做事情之前,它不适合我。

 ... <script> function googleOnLoadCallback(){ alert('googleOnLoadCallback called'); var apisToLoad = 1; // must match number of calls to gapi.client.load() var gCallback = function() { if (--apisToLoad == 0) { //Manual bootstraping of the application var $injector = angular.bootstrap(document, ["myApp"]); console.log("myApp bootstrap complete " + gapi); }; }; gapi.client.setApiKey("my_client_id"); gapi.client.load("translate", "v2", gCallback); } </script> <!-- See https://developers.google.com/api-client-library/javascript/samples/samples --> <script src="https://apis.google.com/js/client.js?onload=googleOnLoadCallback"></script> </head> 

虽然相当多的进展也许值得一提的angular度googleapi ,很好地包装一些谷歌日历和谷歌加API调用,并容易扩展。

检查授权时,您需要将此位添加到控制器中:

 $scope.authenticated = false; $scope.$on("google:authenticated", function(){ $scope.authenticated = true; $scope.$on('googleCalendar:loaded', function(){ # work your magic here # $scope.calendars = googleCalendar.listCalendars(); # $scope.$apply(); }); }); function checkAuth() { setTimeout(function(){ gapi.auth === undefined ? checkAuth() : googleLogin.checkAuth(); }, 20); } checkAuth(); 

我写了一个简单的指令asynchronous加载谷歌地图API:

 // js/directives/gmapAsync.js (function(){ 'use strict'; angular.module('app').directive('gmapAsync', ['$window', '$rootScope', gmapAsync] ); function gmapAsync($window, $rootScope){ var gmapScript = $window.document.createElement('script'); $window.onGmapScriptLoaded = function(){ console.log('google maps script loaded'); $rootScope.gmapApiLoaded = true; $rootScope.$broadcast('gmap.api.loaded'); }; return { restrict: 'A', transclude: false, scope:false, link: function(scope, element, attributes){ if (navigator.onLine) { appendScript(); } else { $window.addEventListener('online',appendScript); } function appendScript(){ gmapScript.type = 'text/javascript'; gmapScript.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' + 'callback=onGmapScriptLoaded'; $window.document.body.appendChild(gmapScript); } } }; } })(); 

然后在你的主控制器中,你可以处理事件:

 // js/controllers/AppCtrl.js (function(){ 'use strict'; angular.module('app').controller('AppCtrl',[$scope,AppCtrl]) function AppCtrl($scope){ $scope.$on('gmap.api.loaded',function(){ // your stuff to init after the api is loaded }); } })(); 

你只需要在body标签中声明指令:

 <!DOCTYPE html> <html> <head></head> <body data-ng-app="app" data-gmap-async data-ng-controller="AppCtrl"> <!-- template body --> <script type="text/javascript" src="js/app.js"></script> <script type="text/javascript" src="js/controllers/AppCtrl.js"></script> <script type="text/javascript" src="js/directives/gmapAsync.js"></script> </body> </html> 

我做了以下

GAPI-service.js

 'use strict'; app.factory('Gapi', ['ENV', function(ENV) { return { load: function load() { console.log('loading google apis...'); if (typeof gapi.client === 'undefined') { setTimeout(load, 500); } else { gapi.client.setApiKey(ENV.googleToken); gapi.client.load('storage', 'v1', function() { console.log('loaded! :)'); var request = gapi.client.storage.buckets.list({ project: ''}); console.log(request); request.execute(function(response) { console.log(response); }); }); } } }; }]); 

的index.html

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> <title>"Txtbinge"</title> </head> <body ng-app="myApp"> <script src="bower_components/jquery/dist/jquery.js"></script> <script src="bower_components/angular/angular.js"></script> <script src="scripts/client.js"></script> <script src="scripts/app.js"></script> <script src="scripts/gapi-service.js"></script> </body> </html> 

controllers.js

 'use strict'; app.controller('AppController', function($scope, $state, Camera, Gapi) { Gapi.load(); }); 

看看这个: https : //github.com/canemacchina/angular-google-client 。

我已经编写了这个模块来在Angular应用程序中使用Google Api或Google Cloud Endpoint。

所以我遇到了同样的问题 把这个代码放在我的工厂里

 var initialize = function() { if(gapi.client == undefined) { setTimeout(function() { initialize() }, 1000); } else { gapi.client.setApiKey("<api_key>"); gapi.client.load('youtube', 'v3').then(function() { console.log("youtube is ready") }); } }; initialize() 

基本上,问题是在加载之前试图调用gapi.client。 如果你只是检查它是否被加载,如果不是,那么再次尝试(你可以设置任何你想要的时间,如果你期望用户在页面加载后相对较快地需要这个设置的话)。

我一直在努力,这一切都为我工作…希望这会有所帮助!

我使用了类似于willlma的解决scheme,但是我的应用程序使用了UI路由器,因此不知道将调用哪个控制器。

我能用JavaScript的承诺解决这个问题。

的index.html

 <html ng-app="myApp"> <head> <script src="angular.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <script src="https://apis.google.com/js/client.js?onload=init"> </head> 

app.js

 var app = angular.module('myApp', []); app.controller('MainController', function($scope, gapiService) { gapiService.then(function(gapi) { // You can use gapi normally here; }); }); app.service('gapiService', function($window) { return new Promise(function(resolve, reject) { if ($window.gapi !== undefined) { console.log("Have gapi already"); resolve($window.gapi); } else { console.log("Waiting for gapi"); $window.init = function() { resolve($window.gapi); } } }); });