AngularFire 0.9.0 登录后(auth)绑定

AngularFire 0.9.0 post-login (auth) Binding

更新:根据 Kato 的回复,我创建了示例代码。 .


只需将 https://www.firebase.com/docs/web/libraries/angular/guide.html#section-angular-authentication results in a working codepen (here it is 处的代码复制为 github 要点)记录我 in/out,但不会 "refresh" 数据,即表达式 {{ user.facebook.displayName }} 并没有真正绑定。

问题:有没有办法让控制器真正绑定到登录状态?

注我:没有直接link到firebase.com上的代码,是

句下出现的代码

Pulling some of these concepts together, we can create a login form with dynamic content based on the user's authentication state

注二:为了让复制的代码生效,你必须用你自己的替换firebase url。

编辑 - 刚刚发现 "code snippet" 功能:

var app = angular.module("sampleApp", ["firebase"]);

// let's create a re-usable factory that generates the $firebaseAuth instance
app.factory("Auth", ["$firebaseAuth", function($firebaseAuth) {
  var ref = new Firebase("https://<your-firebase>.firebaseio.com/");
  return $firebaseAuth(ref);
}]);

// and use it in our controller
app.controller("SampleCtrl", ["$scope", "Auth", function($scope, Auth) {
  $scope.auth = Auth;
  $scope.user = $scope.auth.$getAuth();
}])
<html ng-app="sampleApp">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
    <script src="https://cdn.firebase.com/js/client/2.0.4/firebase.js"></script>
    <script src="https://cdn.firebase.com/libs/angularfire/0.9.0/angularfire.min.js"></script>
    <script src="app.js"></script>
  </head>
  <body ng-controller="SampleCtrl">
    <div ng-show="user">
      <p>Hello, {{ user.facebook.displayName }}</p>
      <button ng-click="auth.$unauth()">Logout</button>
    </div>
    <div ng-hide="user">
      <p>Welcome, please log in.</p>
      <button ng-click="auth.$authWithOAuthPopup('facebook')">Login</button>
    </div>
  </body>
</html>

$getAuth() 是一个同步函数调用,如记录和解释的那样。如果您希望它在每次登录状态更改时异步更新,则需要使用 $onAuth()。

Auth.$onAuth(function(userData) {
   // $timeout needed for AngularFire 0.9.0
   // see https://github.com/firebase/angularfire/issues/510
   $timeout(function() {
      $scope.user = userData;
   });
});

但实际上,您应该 using routes and the resolve method,因此您不必处理范围和控制器中的所有这些身份验证内容,如您现在正在阅读的部分下方的文档中所述。

根据@Kato 的回答,我创建了 2 个示例(带有代码片段和代码笔),供可能像我一样卡在那里的任何人使用。

第一个简单地表明,如@Kato 所示,使用 $onAuth 将模拟绑定。 根据@Kato 的建议,第二个是相同的,但也与 ng-view 一起显示路由的用法。

第一个片段:(codepen here)

var app = angular.module("sampleApp", ["firebase"]);

// let's create a re-usable factory that generates the $firebaseAuth instance
app.factory("Auth", ["$firebaseAuth",
  function($firebaseAuth) {
    var ref = new Firebase("https://glowing-inferno-4287.firebaseio.com/");
    //var ref = new Firebase("https://<replace-with-your-db-id>.firebaseio.com/");
    return $firebaseAuth(ref);
  }
]);

// and use it in our controller
app.controller("SampleCtrl", ["$scope", "Auth", "$timeout",
  function($scope, Auth, $timeout) {
    $scope.auth = Auth;
    $scope.auth.$onAuth(function(userData) {
      // $timeout needed for AngularFire 0.9.0
      // see https://github.com/firebase/angularfire/issues/510
      $timeout(function() {
        $scope.user = userData;
      });
    });
  }
]);
<html ng-app="sampleApp">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
  <script src="https://cdn.firebase.com/js/client/2.0.6/firebase.js"></script>
  <script src="https://cdn.firebase.com/libs/angularfire/0.9.0/angularfire.min.js"></script>

</head>

<body ng-controller="SampleCtrl">
  <div ng-show="user">
    <p>Hello, {{ user.facebook.displayName }}</p>
    <button ng-click="auth.$unauth()">Logout</button>
  </div>
  <div ng-hide="user">
    <p>Welcome, please log in.</p>
    <button ng-click="auth.$authWithOAuthPopup('facebook')">Login</button>
  </div>
</body>

</html>

第二个片段:(codepen here)

var app = angular.module("sampleApp", ["firebase", "ngRoute"]);
// let's create a re-usable factory that generates the $firebaseAuth instance
app.factory("Auth", ["$firebaseAuth",
  function($firebaseAuth) {
    var ref = new Firebase("https://<replace-with-your-db-id>.firebaseio.com/");
    return $firebaseAuth(ref);
  }
]);

// and use it in our controller
app.controller("SampleCtrl", ["$scope", "Auth", "$timeout", "$location", "$route",
  function($scope, Auth, $timeout, $location, $route) {
    $scope.auth = Auth;
    $scope.auth.$onAuth(function(userData) {
      // $timeout needed for AngularFire 0.9.0
      // see https://github.com/firebase/angularfire/issues/510
      $timeout(function() {
        $scope.user = userData;
      });
      $route.reload();
    });

    $scope.login = function() {
      $scope.auth.$authWithOAuthPopup('facebook')
        .then(function() {
          $location.path("/account");
        });
    }
  }
]);

app.controller("AccountCtrl", ["Auth",
  function(Auth) {
    this.userData = Auth.$getAuth();
  }
]);

app.run(["$rootScope", "$location",
  function($rootScope, $location) {
    $rootScope.$on("$routeChangeError", function(event, next, previous, error) {
      // We can catch the error thrown when the $requireAuth promise is rejected
      // and redirect the user back to the home page
      if (error === "AUTH_REQUIRED") {
        $location.path("/");
      }
    });
  }
]);

app.config(["$routeProvider",
  function($routeProvider) {
    $routeProvider.when("/", {
      // the rest is the same for ui-router and ngRoute...
      templateUrl: "views/home.html",
      resolve: {
        // controller will not be loaded until $waitForAuth resolves
        // Auth refers to our $firebaseAuth wrapper in the example above
        "currentAuth": ["Auth",
          function(Auth) {
            // $waitForAuth returns a promise so the resolve waits for it to complete
            return Auth.$waitForAuth();
          }
        ]
      }
    }).when("/account", {
      // the rest is the same for ui-router and ngRoute...
      templateUrl: "views/account.html",
      resolve: {
        // controller will not be loaded until $requireAuth resolves
        // Auth refers to our $firebaseAuth wrapper in the example above
        "currentAuth": ["Auth",
          function(Auth) {
            // $requireAuth returns a promise so the resolve waits for it to complete
            // If the promise is rejected, it will throw a $stateChangeError (see above)
            return Auth.$requireAuth();
          }
        ]
      }
    });
  }
]);
<html ng-app="sampleApp">

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
  <script src="https://cdn.firebase.com/js/client/2.0.6/firebase.js"></script>
  <script src="https://cdn.firebase.com/libs/angularfire/0.9.0/angularfire.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-route.min.js"></script>
</head>

<body ng-controller="SampleCtrl">
  <div ng-show="user">
    <p>Hello, {{ user.facebook.displayName }}</p>
    <button ng-click="auth.$unauth()">Logout</button>
  </div>
  <div ng-hide="user">
    <p>Welcome, please log in.</p>
    <button ng-click="login()">Login</button>
  </div>
  <hr />
  <div ng-view></div>
  <script type="text/ng-template" id="views/home.html">
    home template.
  </script>
  <script type="text/ng-template" id="views/account.html">
    <div ng-controller="AccountCtrl as accntCtrl">
      account template.
      <br />Hello from account page, {{accntCtrl.userData.facebook.displayName}}
    </div>
  </script>
</body>

</html>