异步工厂调用后控制器值未更新(FB API)

时间:2014-04-27 11:36:18

标签: angularjs

我正在建立一个处理Facebook用户身份验证的自定义AngularJS工厂。

在我的控制器中,我绑定到FBUser对象,但我的视图没有为{{user.name}}输出任何内容。但是,如果我将控制器块包裹在1秒内$timeout,那么它可以工作。我以为$rootScope.$apply()会触发我的视图以使用新的FBUser值进行更新,但事实并非如此。理想情况下,我希望尽可能少地在控制器内完成工作,因为将来我希望我的应用程序中的其他模型控制器可以使用工厂中的用户对象。

angular.module('tatsdb.fbauth', ['tatsdb.api'])

.factory('FBAuth', ['$rootScope', function($rootScope) {
  var FBUser = {};
  var FBAuth = {};

  FBAuth.authResponseChange = function() {
    FB.Event.subscribe('auth.authResponseChange', function(response) {
      if (response.status === 'connected') {
        FBAuth.getUserAsync();
      }
      else {
        console.log('not connected');
      }
    });
  };

  FBAuth.getUserAsync = function() {
    FB.api('/me', function(response) {
      console.log('Good to see you, ' + response.name + '.');
      $rootScope.$apply(function() {
        FBUser = response;
      });
    });
  };

  FBAuth.getUser = function() {
    return FBUser;
  };

  FBAuth.logout = function() {
    FB.logout(function(response) {
      FBUser = {};
    });
  };

  return FBAuth;
}])

.run(['$window', 'FBAuth',
  function($window, FBAuth) {
    $window.fbAsyncInit = function() {
      FB.init({
        appId      : '278156419011935',
        status     : true, // check login status
        cookie     : true, // enable cookies to allow the server to access the session
        xfbml      : true  // parse XFBML
      });

      FBAuth.authResponseChange();
    };

    // Load the SDK asynchronously
    (function(d){
     var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement('script'); js.id = id; js.async = true;
     js.src = "//connect.facebook.net/en_US/all.js";
     ref.parentNode.insertBefore(js, ref);
    }(document));
}])

.controller('FBUserController', ['$scope', 'FBAuth', function($scope, FBAuth) {
  $scope.user = FBAuth.getUser();
}]);

1 个答案:

答案 0 :(得分:0)

我要跳过controller并在您的示波器上放置FBUser并将您的异步功能更改为:

FBAuth.getUserAsync = function() {
    FB.api('/me', function(response) {
        console.log('Good to see you, ' + response.name + '.');
        FBUser = response;
    });
  };

这样,FBUser变量就在您的范围内,并会更新响应。此外,您不需要{{user.name}},而您只有{{FBUser.name}}

您目前没有获得该名称的原因是因为控制器功能在之前执行您获得响应。这也是为什么将它包裹在1秒超时中的原因,大部分时间都可以解决这个问题,但这显然不是解决办法。