Angular Js和google api client.js(gapi)
我花了一天的时间才做到这一点,所以我觉得我的经验可能对某人有用。 也许其他一些人会发现改善。
所以我两天前开始使用angularJS。 我希望它可以与Google Cloud Endpoints一起使用来创build后端界面。 这给我带来了麻烦。
gapi的javascript客户端来自asynchronous加载,所以angular度初始化将崩溃gapi未定义。
所以当gapi被初始化时,你需要引导angular度:
- 删除ng-app =“myApp”
- 添加
<script src="https://apis.google.com/js/client.js?onload=googleOnLoadCallback"></script>
-
添加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); } } }); });
- 如何在Google App Engine中导入模块?
- Eclipse和Google App Engine:ImportError:没有名为_sysconfigdata_nd的模块; 无法识别的参数:–high_replication
- 在Python中,如何testing我是否在Google App Engine SDK中?
- 为什么我的java编译器级别不匹配我安装的项目构面?
- 我如何parsingGoogle App Engine中的JSON?
- 您在App Engine上使用了哪些方法进行轻量级Pythonunit testing?
- 使用标准库可以在Go中嵌套模板吗? (Google App Engine)
- 类JavaLaunchHelper在两个实现。 其中一个将被使用。 哪一个是未定义的
- 用Python读App Engine上的文件?