angularFire的$ bind方法的副作用?

时间:2014-03-31 09:58:15

标签: angularjs firebase angularfire

概述:

我在$ firebaseSimpleLogin上使用观察者事件$来触发查询,然后使用一个函数来设置当前登录的用户。

它运行正常但是只要我调用$ firebase的$ bind方法,即使authUser.uid正确且相同,它也会一直返回undefined。

用户服务

 $rootScope.$on('$firebaseSimpleLogin:login', function (e, authUser) {
    var query = $firebase(ref.startAt(authUser.uid).endAt(authUser.uid));
    query.$on('loaded', function () {
      setCurrentUser(query.$getIndex()[0]);
    });
  });

在调用$ bind之前,

authUser.uid返回simpleLogin:26
查询结果有一个对象a24
查询。$ getIndex()[0]返回a24< - 用户名

调用$ bind后,

authUser.uid返回simpleLogin:26
查询结果没有对象
查询。$ getIndex()[0]返回 undefined

为什么在调用$ bind后查询没有返回任何内容,当传入的参数相同时(simpleLogin:26)?

问题似乎只会在我通过3路绑定更改远程数据中的某些内容之后出现。

Firebase结构

firebase
|
|--users
   |
   |--a24
   |   |
   |   |--username: a24
   |   |--md5_hash: "..."
   |   |--name: alice
   |
   |--cate
   |   |
   |   |--username: a25
   |   |--md5_hash: "..."
   |   |--name: cate 

authUser对象两次都返回相同的对象:

Object {provider: "password", id: "27", uid: "simplelogin:27", email: "a24@a24.com", md5_hash: "b20aaf7e9c4d7123f788eb45ac7fd91a"…}
email: "a24@a24.com"
firebaseAuthToken: "eyJ0eXAiOiJKV1QiLCJh..."
id: "27"
isTemporaryPassword: false
md5_hash: "b20aaf7e9c4d7123f788eb45ac7fd91a"
provider: "password"
uid: "simplelogin:27"
__proto__: Object

配置文件编辑控制器($ bind方法调用)

'use strict';

app.controller('ProfileEditCtrl',
  function($scope, $routeParams, User, $firebase, FIREBASE_URL, $location){
    $scope.user = User.findByUsername($routeParams.username );
    $scope.user.$bind($scope, 'boundUser' );
  });

配置文件编辑视图

  <!--Profile Pane-->
  <div class="tab-pane active" id="profile" >
    <form class="form-horizontal" action="">
      <div class="control-group"><label class="control-label" for="name">Name</label>
        <div class="controls">
          <input id="name" type="text" data-ng-model="boundUser.fullname" placeholder="Name"/>
        </div>
      </div>
      <div class="control-group"><label class="control-label" for="email">Cafe Name</label>
        <div class="controls">
          <input id="email" type="text" data-ng-model="boundUser.cafename" placeholder="Cafe Name"/>
        </div>
      </div>
      <div class="control-group">
        <div class="controls"><a href="#/users/{{currentUser.username}}">Save</a></div>
      </div>
    </form>
  </div>

完整的用户服务

'use strict';

app.factory('User', function ($firebase, FIREBASE_URL, $rootScope/*, Auth*/) {
  var ref = new Firebase(FIREBASE_URL + 'users');

  var users = $firebase(ref);

  var User = {
    create: function (authUser, username) {
      /* jshint camelcase: false */
      users[username] = {
        md5_hash: authUser.md5_hash,
        username: username,
        $priority: authUser.uid
      };

      users.$save(username).then(function () {
        setCurrentUser(username);
      });
    },
    findByUsername: function (username) {
      if (username) {
        return users.$child(username);
      }
    },
    getCurrent: function () {
      return $rootScope.currentUser;
    },
    signedIn: function () {
      return $rootScope.currentUser !== undefined;
    }
  };

  function setCurrentUser (username) {
    $rootScope.currentUser = User.findByUsername(username);
  }

  $rootScope.$on('$firebaseSimpleLogin:login', function (e, authUser) {
    var query = $firebase(ref.startAt(authUser.uid).endAt(authUser.uid));
    query.$on('loaded', function () {
      setCurrentUser(query.$getIndex()[0]);
    });
  });

  $rootScope.$on('$firebaseSimpleLogin:Logout', function () {
    delete $rootScope.currentUser;
  });

  return User;
});

2 个答案:

答案 0 :(得分:1)

向传递给$ on事件的函数添加参数。它会有你的身份。

query.$on('loaded', function(uid) { ... });

或引用绑定变量:$ scope.boundUser

像这样:

$rootScope.$on('$firebaseSimpleLogin:login', function (e, authUser) {
var query = $firebase(ref.startAt(authUser.uid).endAt(authUser.uid));

query.$on('loaded', function (data) {
    setCurrentUser(data[0]);
  });

我无法遵循绑定用户变量的逻辑。用户通常不会发生太大变化。此外,您在一个不是单身的控制器中进行此操作。因此,每次再次呈现视图时,您的代码都会运行,指向不需要绑定。如果控制器需要通知用户异步更改,那么请查看angular $ broadcast并创建自己的事件以在控制器中进行监听。

确定。所以我会采取不同的方法。在登录事件:

 ref = <your.firebase.url>+'/users/+'authUser.uid
 var query = $firebase(ref)
 query.$on('loaded', function(userData) {
    setCurrentUser(userData);
 });

不确定我是否完全理解您的问题,但这会填充数据并且数据将是双向绑定的。这意味着,如果在完成此查询后服务器的任何数据发生更改,则数据将在User对象中更改。只要您不复制数据并因此取消引用它。希望有所帮助。

答案 1 :(得分:1)

这确实是早期angularfire 0.6.0中的一个错误。

问题不再来自angularfire 0.7.0