J'ai donc essayé les modèles suivants en essayant d'intégrer ceci:

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

-

Je viens également d'essayer de le faire dans l'en-tête et d'utiliser le bouton de connexion normal:

HTML :

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

DANS L'EN-TÊTE :

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

Quoi que je fasse, je n'arrive pas à comprendre comment déconnecter un utilisateur. Dans mon contrôleur, lorsque j'essaye de faire gapi.auth.signOut();, cela indique que gapi n'est pas défini

MODIFIER :

J'ai également essayé de me connecter à cela pour déconnecter une personne en cours d'exécution, mais idéalement, je voudrais que la déconnexion fonctionne n'importe où et pas seulement lorsque la page se charge. Je ne sais pas vraiment où le mettre ou la bonne façon de le faire:

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

MODIFIER # 2:

J'ai également essayé de créer cette usine avec une résolution sur mon ui-router mais il n'obtient pas les données à temps ou du tout

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

})

MODIFIER N ° 3:

J'ai essayé de créer un service mais je continue à recevoir l'erreur suivante pour une raison quelconque pour même le tester:

Erreur: undefined n'est pas un objet (évaluation de '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());

}])
3
bryan 16 janv. 2017 à 21:22

2 réponses

Meilleure réponse

Je m'appuie sur mon violon de ma précédente réponse à une question connexe. Fondamentalement, j'ai ajouté une fonction à la portée du contrôleur qui serait appelée lorsqu'un utilisateur clique sur le bouton de déconnexion.

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

J'ai utilisé l'extrait de code fourni par la documentation Google et cela a semblé fonctionner immédiatement.
Faites attention lorsque vous modifiez des variables dans la portée, vous devez encapsuler vos modifications de portée dans $scope.$apply pour que angular force la vérification des modifications de la portée.

Vous pouvez trouver le code complet dans ce violon.
(Je supprimerai ce projet Google api à un moment donné, alors remplacez la clé API par la vôtre si cela ne fonctionne pas)

Il s'agit d'un code de démonstration, donc si vous le mettez réellement dans le projet, je vous recommande de cacher une partie de la complexité derrière les services et les directives.


Mise à jour: si vous souhaitez utiliser un service, vous devrez utiliser fortement les promesses angularjs, voir $ a documents.

Voici un exemple de la façon dont vous pouvez créer un service à l'aide de promesses et de rappels. Il n'y a pas de moyen simple de contourner l'enfer des rappels. Mais j'espère que l'intégration de ces choses dans un service résoudra partiellement cela.

Voici un un violon mis à jour tirant parti du service. Voici le code 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;
      };
    }

}]);

Fondamentalement, dans la fonction de chargement, vous englobez la complexité du chargement de gapi et auth2. Une fois la promesse de chargement résolue dans votre contrôleur, vous êtes certain que signIn, signOut, etc. fonctionnera car il est chargé.

1
Community 23 mai 2017 à 11:46

J'ai adopté une approche légèrement différente. Cependant, je ne suis pas assez bon pour expliquer pourquoi votre code ne fonctionne pas et cela fonctionne pour moi. J'espère que quelqu'un d'autre pourra vous aider.

Voici mon approche. Faites-moi savoir si cela vous aide.

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

Login-directive.js

angular.module('app', []).directive("loginButton", function() {
  return {
    restrict: 'E',
    scope: {},
    templateUrl: 'login/login.html',
    controller: 'LoginController'
  }
});
0
Emma 20 janv. 2017 à 17:21