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

Angularjs 异步工厂调用后未更新控制器值(FB API),angularjs,Angularjs,我正在建立一个定制的AngularJS工厂,用于处理Facebook用户身份验证 在我的控制器中,我绑定到FBUser对象,但是我的视图没有为{{user.name}输出任何内容。但是,如果我在1秒内包装控制器块$timeout,它就会工作。我以为$rootScope.$apply()会触发我的视图使用新的FBUser值进行更新,但事实并非如此。理想情况下,我希望在控制器内尽可能少地工作,因为将来我希望我的应用程序中的其他模型控制器使用工厂中的用户对象 angular.module('tatsd

我正在建立一个定制的AngularJS工厂,用于处理Facebook用户身份验证

在我的控制器中,我绑定到
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();
}]);

我建议跳过
控制器
,在您的作用域上设置
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秒超时内包装它在大多数情况下都会起作用,但这显然不是解决方案。

我应该如何在我的作用域中包含FBUser,一个在工厂内声明的变量?我只是在视图中写{{FBUser.name}}吗?我知道控制器在得到响应之前正在执行,这是产生这个问题的主要原因。一旦FBUser.name被填充,我如何更新视图?@Fenda我自己也会使用服务。该服务将保存一个成员
FBUser
,该成员将被分配从API获得的响应。然后在我的控制器中,我将执行
$scope.FBUser=facebookApiService.FBUser
在视图中,我将执行
{{{FBUser.name}
。我还没有与工厂合作过,我发现使用服务更容易、更直观。这不是我已经在做的事情吗?FBUser被分配来自API的响应,我从控制器绑定到它。据我所知,使用服务或工厂在这里是一样的。@Fenda另一件可以帮助您的事情(为我多次解决了相同的问题)是在范围中的另一个参数下有
FBUser
。例如,
$scope.User.FBUser=FBAuth.getUser()
然后在您的视图中
{{User.FBUser.name}
。我尝试切换到一个服务和您建议的内容,但它不起作用。问题仍然是在填充FBUser之前正在执行控制器。我们需要以某种方式告诉视图FBUser已更新?