【问题标题】:Ensure binding for $watch when $firebaseArray or $firebaseObject returns empty确保 $firebaseArray 或 $firebaseObject 返回空时绑定 $watch
【发布时间】:2015-12-09 22:50:15
【问题描述】:

我正在使用 Angularfire,有一种情况是 $firebaseArray$firebaseObject 一开始什么都不返回。这是因为它是空的或还不存在。但我想一直为那个对象/数组做 $watch 。稍后再说,节点实际上是存在的。原始的$firebaseArray$firebaseObject 不会触发$watch 事件。

即使节点为空/一开始不存在,我如何确保 $watch 的绑定发生?当我创建一个新用户并且某个节点中没有任何内容时会发生这种情况。

更新 1

http://plnkr.co/edit/tQur74nkRIE9ZOiJUAgf?p=preview

JS

var app = angular.module('plunker', ['firebase']);
var Ref = new Firebase('https://so32556276.firebaseio.com');

app.controller('MainCtrl', function($scope, $firebaseObject) {
  $scope.data = $firebaseObject(Ref.child('user'));

  $scope.data.$loaded().then(function(res) {
    $scope.data.$watch(function(e) {
      console.log('Something changed');
      console.log(e);
    });
  });

  $scope.changeName = function() {
    $scope.data.name = "test2";
    $scope.data.$save();
  }

  $scope.changeAge = function() {
    $scope.data.age = "10";
  }
});

HTML

  <body ng-controller="MainCtrl">
    <p>Hello {{data.name}}!</p>
    <p>Your age is {{data.age}}!</p>
    <a href="" ng-click="changeName()">Change Name</a><br>
    <a href="" ng-click="changeAge()">Change Age</a>
  </body>

Firebase

如果我点击“更改名称”,你可以在这里看到日志事件:

Something changed
app.js:10 Object {event: "value", key: "user"}

如果我点击“更改年龄”,虽然前端可以检测到变量,但$watch 对此没有可见性。控制台中没有任何内容。

任何线索如何避免这种情况?

【问题讨论】:

  • 我用上面的代码更新了。
  • 感谢代码和 plunkr。有了这些,很容易找出问题所在。下面回答。清理上面的 cmets。

标签: javascript angularjs firebase angularfire


【解决方案1】:

在我看到人们尝试使用$loaded() 的大多数情况下,他们仍然停留在“首先加载数据然后执行...”的心态中。 Firebase(以及因此 AngularFire)是一个“同步这些数据,并且每当它发生变化时......”系统。您使用$watch() 绝对是正确的方法,您只是在错误的时间附加了它。

app.controller('MainCtrl', function($scope, $firebaseObject) {
  $scope.data = $firebaseObject(Ref.child('user'));

  $scope.data.$loaded().then(function(res) {
    $scope.data.$watch(function(e) {
      console.log('Something changed');
      console.log(e);
    });
  });

一旦从 Firebase 加载初始数据,$loaded() 承诺就会实现;或者一个 Firebase 已确定还没有数据。您只需在初始数据加载之后注册$watch() 处理程序,因此它只会在此之后触发更改。

解决方案是立即将$watch() 处理程序附加到$firebaseObject

app.controller('MainCtrl', function($scope, $firebaseObject) {
  $scope.data = $firebaseObject(Ref.child('user'));
  $scope.data.$watch(function(e) {
    console.log('Something changed');
    console.log(e);
  });

【讨论】:

    【解决方案2】:

    对我来说,听起来您只是想扩展服务并收听$$added$$updated 事件。

    这是一个关于如何扩展的示例。

    var userFactory = $firebaseArray.$extend({    
        //This is called anytime a new user_node is added   
        $$added: function(dataSnapshot){
            var user = dataSnapshot.val(); //This is the data
            var user_key = dataSnapshot.key(); //The users id
            user.$id = user_key;  
            //This user.$id is important if you want to 
            //make modifications to the user 
    
    
            //Perhaps add new properties to your user
            return user; 
        },
        $$updated: function(dataSnapshot){
           //An update has been made
           var changed = false; 
           //Go through your data, if changed change the variable. 
           return changed;
        }
    });
    
    //Instantiate
    var firebaseRef = new Firebase("your_ref");
    var firebaseUserConnection = new userFactory(firebaseRef); 
    

    您还可以收听其他事件,例如$$removed 等等,看看Extending the service

    【讨论】:

      猜你喜欢
      • 2016-11-25
      • 1970-01-01
      • 2016-04-16
      • 2016-04-20
      • 2017-08-14
      • 2015-06-13
      • 1970-01-01
      • 2013-08-29
      • 2017-09-04
      相关资源
      最近更新 更多