【问题标题】:Side effects of angularFire's $bind method?angularFire 的 $bind 方法的副作用?
【发布时间】:2014-03-31 09:58:14
【问题描述】:

概述:

我使用观察者事件 $on $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
query.$getIndex()[0] 返回a24

在调用 $bind 之后,

authUser.uid 返回 simpleLogin:26
查询结果没有对象
query.$getIndex()[0] 返回 未定义

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

问题似乎只出现在我通过 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;
});

【问题讨论】:

  • 所以基本上为什么一旦firebase上的数据发生更改,下面的sn-p就不起作用: $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]); }) ; });

标签: angularjs firebase angularfire


【解决方案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);
 });

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

【讨论】:

  • 想详细说明一下?我需要将授权用户对象的名称传递给我不知道的函数 setCurrentUser(),因此 $firebase(ref.startAt(authUser.uid).endAt(authUser.uid));然后执行 $getIndex()[0],它应该返回对象的名称。但即使 authUser.uid 正确传递到查询中,查询也不会获取对象。
  • 问题是一旦远程数据发生变化,无论是通过3路绑定还是$set,上面的查询都将停止工作,所以data[0]什么都不返回
  • 如果远程数据发生变化……那么这个变量(数据)也会发生变化。如果您不希望它更改,则只需使用 .once。
【解决方案2】:

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

angularfire 0.7.0 不再存在问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-31
    • 2011-10-17
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    相关资源
    最近更新 更多