2017-01-16 319 views
3

簽署了與谷歌登錄(GAPI)所以我曾嘗試以下模板試圖整合this麻煩與angularjs

HTML

<google-sign-in-button button-id="login-button" options="options"></google-sign-in-button> 

CSS

.directive('googleSignInButton', function() { 
    return { 
     scope: { buttonId: '@', options: '&' }, 
     template: '<div></div>', 
     link: function(scope, element, attrs) { 
     var div = element.find('div')[0]; 
     div.id = attrs.buttonId; 
     gapi.signin2.render(div.id, scope.options()); 
     } 
    }; 
}) 

-

我也只是試圖在頭這樣做的,使用按鈕,在常規登錄:

HTML

<div class="g-signin2" data-onsuccess="onSignIn"></div> 

在頭

<script> 
    window.onLoadCallback = function(){ 
     gapi.auth2.init({ 
      client_id: '123.apps.googleusercontent.com' 
     }); 
    } 
</script> 

無論我做什麼,我都無法弄清楚如何登錄一個用戶。在我的控制器,當我嘗試做gapi.auth.signOut();它說GAPI未定義

編輯

我也試着在這個涉獵登錄一個人出來上運行,但理想我想在任何地方進行註銷工作,而不僅僅是在頁面加載時進行。我真的不知道在哪裏把它和正確的方法來做到這一點:

.run(function ($rootScope, $state) { 
    gapi.load('auth2', function() { 
     auth2 = gapi.auth2.init(); 
     auth2.then(function(){ 
      auth2.signOut(); 
     }); 
    }); 
}) 

編輯#2:

我也試圖在我的UI創建這個工廠有決心-router但它沒有得到及時或根本

.factory('Auth', function($http, $state, $q, $rootScope) { 
    var factory = { loggedIn: loggedIn }; 
    return factory; 

    function loggedIn() { 
     gapi.load('auth2', function() { 
      auth2 = gapi.auth2.init(); 
      auth2.then(function(){ 
       return auth2.isSignedIn.get(); 
      }); 
     }); 
    } 

}) 

編輯#3的數據:

我試圖創建一個服務,但我不斷收到以下錯誤出於某種原因,甚至測試:

Error: undefined is not an object (evaluating 'gapi.auth2.init')

.service('googleService', ['$http', '$rootScope', '$q', function ($http, $rootScope, $q) { 

    var self = this; 

    this.signedIn = function() { 
     auth2 = gapi.auth2.init(); 
     auth2.then(function(){ 
      return auth2.isSignedIn.get(); 
     }); 
    } 

    this.signOut = function(){ 
     var auth2 = gapi.auth2.getAuthInstance(); 
     auth2.signOut().then(function() { 
      console.log('User signed out.'); 
     }); 
    } 

}]) 

.controller('login', ['$rootScope', '$scope', '$q', 'googleService', function ($rootScope, $scope, $q, googleService) { 
    console.log(googleService.signedIn()); 

}]) 
+0

請讓我知道,如果你仍然遇到這個問題,我給你一個工作的例子,但要真正指出爲什麼你的代碼不工作,我需要一個小提琴來看看自己 – sniels

回答

1

我從以前answer on a related question建立在我的小提琴。 基本上我添加的是控制器作用域,當用戶點擊登出按鈕時會被調用。

angular.module('app', []) 
    .controller('MainController', ['$scope', 
    function($scope) { 
     $scope.isSignedIn = false; 
     ... 
     $scope.signOut = function(){ 
     var auth2 = gapi.auth2.getAuthInstance(); 
     auth2.signOut().then(function() { 
      $scope.$apply(function(){ 
      $scope.isSignedIn = false; 
      console.log('User signed out.'); 
      }); 
     }); 
     } 
    } 
    ]) 

我使用了谷歌文檔提供的代碼片段,這似乎立即工作。
修改範圍內的變量時請注意,您必須將範圍更改包含在$scope.$apply中,以便強制檢查範圍內的更改。

你可以在這個fiddle找到完整的代碼。
(我將刪除在某些時候這個谷歌API的項目,所以換成你自己的API密鑰,如果它不工作)

這是演示代碼,所以如果你實際上把這個項目,我'd建議隱藏服務和指令背後的一些複雜性。


更新:如果你想使用一個服務,你必須大量使用angulars承諾,請參閱$q docs

下面是關於如何使用承諾和回調來創建服務的示例。 有沒有簡單繞過回撥地獄。但我希望將這些東西包裝到服務中會部分解決這個問題。

這是一個updated fiddle利用該服務。 這是js代碼:

angular.module('app', []) 
    .controller('MainController', ['$scope','googleService', 
    function($scope, googleService) { 
     $scope.isSignedIn = false; 
     googleService.load().then(function(){ 
     $scope.signIn = function(){ 
      googleService.signIn().then(function(){ 
      $scope.isSignedIn = googleService.isSignedIn(); 
      }); 
     }; 

     $scope.signOut = function(){ 
      googleService.signOut().then(function(){ 
      $scope.isSignedIn = googleService.isSignedIn(); 
      }); 
     }; 
     }); 
    } 
    ]) 
    .service('googleService', ['$q', function ($q) { 
    var self = this; 
    this.load = function(){ 
     var deferred = $q.defer(); 
     gapi.load('auth2', function(){ 
     var auth2 = gapi.auth2.init(); 
     //normally I'd just pass resolve and reject, but page keeps crashing (probably gapi bug) 
     auth2.then(function(){ 
      deferred.resolve(); 
     }); 
     addAuth2Functions(auth2); 
     }); 
     return deferred.promise; 
    }; 

    function addAuth2Functions(auth2){ 
     self.signIn = function() { 
     var deferred = $q.defer(); 
     auth2.signIn().then(deferred.resolve, deferred.reject); 
     return deferred.promise; 
     }; 

     self.isSignedIn = function(){ 
     return auth2.isSignedIn.get(); 
     } 

     self.signOut = function(){ 
     var deferred = $q.defer(); 
     auth2.signOut().then(deferred.resolve, deferred.reject); 
     return deferred.promise; 
     }; 
    } 

}]); 

基本上,負載的功能裏面你包裹裝載GAPI和auth2的複雜性。在您的控制器中加載承諾解決後,您確定signIn,signOut等工作,因爲它被加載。

+0

非常感謝小提琴。我唯一感到困惑的是如何獲取用戶信息並檢查他們是否在另一個範圍/控制器中登錄。如果我將其添加到另一個範圍gapi通常是不確定的。 – bryan

+0

在我的'EDIT#3'中,我試圖創建一個服務,並遇到了一個障礙。你有什麼建議嗎? – bryan

+0

@bryan我使用服務示例更新了代碼。祝你好運。 – sniels

0

我採取了一個稍微不同的方法。雖然,我不夠好解釋爲什麼你的代碼不起作用,這對我很有用。希望別人可以幫助解決這個問題。

這是我的方法。讓我知道這是否有幫助。

的login.html

<script>var gapiOnLoadCallback = function() { window.gapiOnLoadCallback(); }</script> 
<script src="https://apis.google.com/js/platform.js?onload=gapiOnLoadCallback" async defer></script> 

<div id="googleLoginButton"></div> 

<button ng-show="signedIn" ng-click="signOut()">Sign Out</button> 

login.js

angular.module('app', []) 
.controller('LoginController', ['$window','$scope', function($window, $scope) { 

    $window.gapiOnLoadCallback = function() { 

    gapi.signin2.render('googleLoginButton', { 
     'onsuccess': onSuccess, 
     'onfailure': onFailure 
    }); 
    } 

    var onSuccess = function(googleUser) { 
    // Success handling here 
    }; 

    var onFailure = function() { 
    // Failure handling here 
    }; 

    $scope.signOut = function() { 
    var auth2 = gapi.auth2.getAuthInstance(); 
    auth2.signOut().then(function() { 
     // Some UI update 
    }); 
    }; 
}; 

登錄-directive.js

angular.module('app', []).directive("loginButton", function() { 
    return { 
    restrict: 'E', 
    scope: {}, 
    templateUrl: 'login/login.html', 
    controller: 'LoginController' 
    } 
});