0

Google OAuth2 code is based on https://developers.google.com/api-client-library/javascript/features/authentication

LoginView has a few functions, each function calls another function.

By the time it gets to checkAuth function, the this.handleAuthResult returns undefined because checkAuth was called inside the setTimeout by handleClientLoad.

How to deal with this context problem? And can I do the same for my variables - scope, clientId, apiKey instead of making them global?

define(['underscore','jquery','backbone','text!templates/login.html','async!https://apis.google.com/js/client.js!onload'], function(_, $, Backbone, loginTpl) {
  var LoginView = Backbone.View.extend({
    template: _.template(loginTpl),

    initialize: function() {
      clientId = '';
      apiKey = '';
      scopes = 'https://www.googleapis.com/auth/plus.me';

      this.handleClientLoad();
    },

    render: function() {
      this.$el.html(this.template());
      return this;
    },

    handleClientLoad: function() {
      gapi.client.setApiKey(apiKey);
      window.setTimeout(this.checkAuth, 1);
    },

    checkAuth: function() {
      gapi.auth.authorize({ client_id: clientId, scope: scopes, immediate: true }, this.handleAuthResult);
    },

    handleAuthResult: function(authResult) {
      var authorizeButton = this.$el.find('#authorize-button');

      if (authResult && !authResult.error) {
        console.log('Authorized!');
        this.makeApiCall();
      } else {
        authorizeButton.onclick = this.handleAuthClick;
      }
    },

    handleAuthClick: function(event) {
      gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, this.handleAuthResult);
      return false;
    },

    makeApiCall: function() {
      gapi.client.load('plus', 'v1', function() {
        var request = gapi.client.plus.people.get({
          'userId': 'me'
        });
        request.execute(function(resp) {
          var authorizeButton = this.$el.find('#authorize-button');
          localStorage.isAuthenticated = true;
          Backbone.history.navigate('', true);
        });
      });
    }
  });

  return LoginView;
});
4

1 回答 1

3

The setTimeout in handleClientLoad is the issue:

window.setTimeout(this.checkAuth, 1);

When 'window.setTimeout' is executed after 1ms and it is no longer executed in LoginView scope.

You can use '_.bind' to bind the execution to this.

window.setTimeout(_.bind(this.checkAuth, this), 1);

You can also read 'this' posting.

Hope this help!

于 2013-10-08T02:18:51.137 回答