Google Signin button in AngularJS sometimes does not show up

前端 未结 2 1754
野的像风
野的像风 2020-12-09 16:55

I followed this link https://developers.google.com/identity/sign-in/web/sign-in to get Google Signin on Angular-based website.

I have seen some weird behavior. The

相关标签:
2条回答
  • 2020-12-09 17:34

    I found another way to solve the problem a liitle bit simply.

    The explanation from @sniel is perfect but I will let you know more simple solution.

    you can use below sample code very simiraliry with using $watch https://developers.google.com/identity/sign-in/web/build-button

    <!-- html part -->
    <div id="signInButton"></div>
    
    
    //gapi is Asynchronously loaded so you need to watch
    $scope.$watch('gapi', function(newValue,oldVale){
            if(newValue !== oldVale){
                if(gapi){
                    gapi.signin2.render('signInButton',
                        {
                            'onsuccess': $scope.onSuccess,
                            'onfailure': $scope.onFailure,
                            'scope':'https://www.googleapis.com/auth/plus.login'
                        }
                    );
                }
            }
        });
    
    0 讨论(0)
  • 2020-12-09 17:57

    My guess is that the platform.js script waits for the DOM-ready event and then looks for your div with the "g-signin2"-class. Though, in Angularjs things work a little different. The reason that it works sometimes, is because sometimes your div has been rendered by Angular and sometimes is hasn't been rendered before the Dom-ready event. There's documentation on how to get the same result with your own javascript. I made an example that follows your routing.

    <!doctype html>
    <html lang="en" ng-app="app">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div ng-view></div>
    
    <script src="https://apis.google.com/js/platform.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
    <script src="https://code.angularjs.org/1.4.6/angular-route.min.js"></script>
    <script>
        angular.module('app',['ngRoute'])
                .config(['$routeProvider',function($routeProvider){
                    $routeProvider
                            .when('/log-in', {
                                template: '<button ng-click="logInCtrl.onLogInButtonClick()">Log In</button>',
                                controller: 'LogInController',
                                controllerAs: 'logInCtrl'
                            }).otherwise({
                                redirectTo:'/log-in'
                            });
                }])
                .controller('LogInController',function(){
                    var self = this; //to be able to reference to it in a callback, you could use $scope instead
                    gapi.load('auth2', function() {//load in the auth2 api's, without it gapi.auth2 will be undefined
                        gapi.auth2.init(
                                {
                                    client_id: 'CLIENT_ID.apps.googleusercontent.com'
                                }
                        );
                        var GoogleAuth  = gapi.auth2.getAuthInstance();//get's a GoogleAuth instance with your client-id, needs to be called after gapi.auth2.init
                        self.onLogInButtonClick=function(){//add a function to the controller so ng-click can bind to it
                            GoogleAuth.signIn().then(function(response){//request to sign in
                                console.log(response);
                            });
                        };
                    });
                });
    </script>
    </body>
    </html>

    Or as a directive:

    <!doctype html>
    <html lang="en" ng-app="app" ng-controller="MainController">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <google-sign-in-button on-sign-in="onSignIn(response)" g-client-id="CLIENTID.apps.googleusercontent.com"></google-sign-in-button>
    
    <script src="https://apis.google.com/js/platform.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
    <script>
        angular.module('app',[])
                .controller('MainController',['$scope', function ($scope) {
                    $scope.onSignIn=function(response){
                        console.log(response);
                    }
                }])
                .directive('googleSignInButton',function(){
                    return {
                        scope:{
                            gClientId:'@',
                            callback: '&onSignIn'
                        },
                        template: '<button ng-click="onSignInButtonClick()">Sign in</button>',
                        controller: ['$scope','$attrs',function($scope, $attrs){
                            gapi.load('auth2', function() {//load in the auth2 api's, without it gapi.auth2 will be undefined
                                gapi.auth2.init(
                                        {
                                            client_id: $attrs.gClientId
                                        }
                                );
                                var GoogleAuth  = gapi.auth2.getAuthInstance();//get's a GoogleAuth instance with your client-id, needs to be called after gapi.auth2.init
                                $scope.onSignInButtonClick=function(){//add a function to the controller so ng-click can bind to it
                                    GoogleAuth.signIn().then(function(response){//request to sign in
                                        $scope.callback({response:response});
                                    });
                                };
                            });
                        }]
                    };
                });
    </script>
    </body>
    </html>

    After writing the previous examples I found a better and easier way to implement it. With this code you inherit the same button as you normally would.

    <!doctype html>
    <html lang="en" ng-app="app" ng-controller="MainController">
    
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
      <meta name="google-signin-client_id" content="CLIENTID.apps.googleusercontent.com">
    </head>
    
    <body>
      <google-sign-in-button button-id="uniqueid" options="options"></google-sign-in-button>
    
      <script src="https://apis.google.com/js/platform.js"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
      <script>
        angular.module('app', [])
          .controller('MainController', ['$scope',
            function($scope) {
              //for more options visit https://developers.google.com/identity/sign-in/web/reference#gapisignin2renderwzxhzdk114idwzxhzdk115_wzxhzdk116optionswzxhzdk117
              $scope.options = {
                'onsuccess': function(response) {
                  console.log(response);
                }
              }
            }
          ])
          .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()); //render a google button, first argument is an id, second options
              }
            };
          });
      </script>
    </body>
    
    </html>

    0 讨论(0)
提交回复
热议问题