当服务器数据发生变化时,$loaded无法正常工作



我是firebase和angularjs的新手。对于我的销售申请,我想两者都用。所以,在我的应用程序中,我使用AngularJS v1.5.8 + Firebase v3.3.0 + AngularFire 2.0.2。我在firebase db中有sales和users对象,并且有一个业务逻辑,即一个用户可以销售多个产品,但一个产品只能有一个所有者(user)。

下面是数据库中的userssales对象:
{
  "sales" : {
    "-KQlb5N6A9rclc5qcWGD" : {
      "price" : 8,
      "quantity" : {
        "count" : 12,
        "type" : "porsiyon"
      },
      "status" : "sale",
      "title" : "Patlicanli Borek",
      "user" : "-KQ52OJd-lwoDIWzfYFT"
    },
    "-KQlcScsq8cidk7Drs04" : {
      "price" : 12,
      "quantity" : {
        "count" : 10,
        "type" : "porsiyon"
      },
      "status" : "sale",
      "title" : "Deneme",
      "user" : "-KQ5-mZBt6MhYy401gGM"
    },
    "-KQzXHwOv2rC73scjV46" : {
      "price" : 12,
      "quantity" : {
        "count" : 11,
        "type" : "porsiyon"
      },
      "status" : "sale",
      "title" : "Pacanga",
      "user" : "-KQ5-mZBt6MhYy401gGM"
    },
    "-KSCBgpArtnKunUuEuVr" : {
      "price" : 15,
      "quantity" : {
        "count" : 15,
        "type" : "porsiyon"
      },
      "status" : "sale",
      "title" : "Iskembe",
      "user" : "-KQ52OJd-lwoDIWzfYFT"
    }
  },
  "users" : {
    "-KQ5-mZBt6MhYy401gGM" : {
      "address" : "Halkali kucukcekmece",
      "email" : "burak.kahraman@gmail.com",
      "name" : "Burak Hero",
      "nick" : "Burak'in Mutfagi"
    },
    "-KQ52OJd-lwoDIWzfYFT" : {
      "address" : "Izmir kaynaklar",
      "email" : "ayse@gmail.com",
      "name" : "Ayse Kahraman",
      "nick" : "Ayse'nin Mutfagi"
    }
  }
}

我想做的是当我的应用程序打开时,它会显示所有销售以及相应的用户详细信息。(就像letgo应用程序的主页一样)这意味着我应该在销售和用户对象之间实现一个简单的连接。就我在互联网和api文档中搜索到的,没有办法在对firebase的单个调用中实现这种连接。(请纠正我,如果我错了)所以我使用下面的方法使用$loaded函数在我的SalesService实现连接。

angular.
  module('core.sales')
  .service('SalesService', function ($firebaseArray, $firebaseObject, UsersService) {
this.getAllSalesJoin = function () {
      var sales;
      var refSales = firebase.database().ref('sales');
      sales = $firebaseObject(refSales);
      sales.$loaded()
        .then(function () {
          angular.forEach(sales, function (sale) {
            var saleUser = UsersService.getUserDetail(sale.user);
            saleUser.$loaded()
              .then(function () {
                sale.user = saleUser;
              });
          });
        });
      return sales;
    };
 });

正如您所看到的,我正在获取所有销售,在它完成后,通过调用另一个UsersService来循环获取和设置相关的用户详细信息,如下所示

angular.
  module('core.users')
  .service('UsersService', function ($firebaseArray,$firebaseObject) {
this.getUserDetail = function (userId) {
      var user;
      var refUser = firebase.database().ref('users/'+userId);
      user = $firebaseObject(refUser);
      return user;
    };
  });

到目前为止一切顺利,当我调用SalesService时。getAllSalesJoin函数并使用<pre>{{$ctrl.allSales | json}}</pre>打印JSON对象,一切都如我所愿,下面是模板中的控制器代码和打印的JSON对象。

angular.
  module('saleList').
  component('saleList', {
    templateUrl: 'MCTs/sale-list/sale-list-template.html',
    controller: ['SalesService','UsersService', function SaleListController(SalesService,UsersService,$scope) {
          this.allSales = SalesService.getAllSalesJoin();  
 }]
  });

模板显示合并的对象

{
  "$id": "sales",
  "$priority": null,
  "-KQlb5N6A9rclc5qcWGD": {
    "price": 8,
    "quantity": {
      "count": 12,
      "type": "porsiyon"
    },
    "status": "sale",
    "title": "Patlicanli Borek",
    "user": {
      "$id": "-KQ52OJd-lwoDIWzfYFT",
      "$priority": null,
      "address": "Izmir kaynaklar",
      "email": "ayse@gmail.com",
      "name": "Ayse Kahraman",
      "nick": "Ayse'nin Mutfagi"
    }
  },
  "-KQlcScsq8cidk7Drs04": {
    "price": 12,
    "quantity": {
      "count": 10,
      "type": "porsiyon"
    },
    "status": "sale",
    "title": "Deneme",
    "user": {
      "$id": "-KQ5-mZBt6MhYy401gGM",
      "$priority": null,
      "address": "Halkali kucukcekmece",
      "email": "burak.kahraman@gmail.com",
      "name": "Burak Hero",
      "nick": "Burak'in Mutfagi"
    }
  },
.....

但是的问题是是,当服务器数据发生变化时(输入新的销售或删除旧的销售),angular会自动理解这个变化,但它在没有实现或调用我的join函数的情况下将更改应用到视图中,它只是打印销售对象而不是与用户合并的对象。以下是服务器数据更改后的显示对象:

{
  "$id": "sales",
  "$priority": null,
  "-KQlb5N6A9rclc5qcWGD": {
    "price": 8,
    "quantity": {
      "count": 12,
      "type": "porsiyon"
    },
    "status": "sale",
    "title": "Patlicanli Borek",
    "user": "-KQ52OJd-lwoDIWzfYFT"
  },
  "-KQlcScsq8cidk7Drs04": {
    "price": 12,
    "quantity": {
      "count": 10,
      "type": "porsiyon"
    },
    "status": "sale",
    "title": "Deneme",
    "user": "-KQ5-mZBt6MhYy401gGM"
  },
....

我很困惑为什么它的行为是那样的?是我的方式来实现使用$loaded连接错误吗?或者我应该使用另一种方法来实现这种连接?我期待着看到你无价的建议和想法。

$loaded()仅在加载初始数据时触发。参考文档(重点是我的):

返回一个promise,当从数据库下载初始对象数据时被解析。

这就是我经常说:"如果你用的是$loaded(),那你做错了"的主要原因。

你是对的,需要与多个调用连接数据。在AngularFire中,您可以扩展$firebaseArray来执行这样的操作。有关如何做到这一点的一个很好的例子,请参阅Kato的回答:使用AngularFire

根据id在路径之间连接数据

感谢frank的指导。我读了你所有的建议,找到了解决办法。对于贡献stackoverflow知识和帮助他人,这里是问题的完整解决方案。

我首先创建了一个新的工厂,扩展$firebaseArray并覆盖$$added和$$updated方法,以便在每次更新或添加数据时执行join to Users对象。

angular.
  module('core.sales').factory("SalesFactory", function ($firebaseArray, Sales) {
    return $firebaseArray.$extend({
      $$added: function (snap) {
        return new Sales(snap);
      },
      $$updated: function (snap) {
        return this.$getRecord(snap.key).update(snap);
      }
    });
  });
angular.
  module('core.sales').factory("Sales", function ($firebaseArray, $firebaseObject) {
    var refUsers = firebase.database().ref('users');
    function Sales(snapshot) {
      this.$id = snapshot.key;
      this.update(snapshot);
    }
    Sales.prototype = {
      update: function (snapshot) {
        var oldTitle = angular.extend({}, this.title);
        var oldPrice = angular.extend({}, this.price);
        var oldQuantity = angular.extend({}, this.quantity);
        this.userId = snapshot.val().user;
        this.title = snapshot.val().title;
        this.status = snapshot.val().status;
        this.price = snapshot.val().price;
        this.quantity = snapshot.val().quantity;
        this.userObj = $firebaseObject(refUsers.child(this.userId));
        if (oldTitle == this.title && oldPrice == this.price && 
        oldQuantity.count == this.quantity.count && oldQuantity.type == this.quantity.type)
          return false;
        return true;
      },
    };
    return Sales;
  });
如您所见,SalesFactory使用了另一个名为Sales的工厂。在这个特定的工厂中,我检索Sales对象的所有属性,并将它们分配给相应的属性。在这种情况下,我通过创建新属性this。userobj 来执行连接到Users对象有一件事是缺少的,只是调用新的工厂,而不是$firebaseArray
this.getAllSalesArray = function () {
      var sales;
      var refSales = firebase.database().ref('sales');
      sales = SalesFactory(refSales);
      return sales;
    };

总而言之,所有与相关用户连接的Sales对象都打印到视图中,

[
  {
    "$id": "-KQlb5N6A9rclc5qcWGD",
    "userId": "-KQ52OJd-lwoDIWzfYFT",
    "title": "Patlicanli Borek",
    "status": "sale",
    "price": 12,
    "quantity": {
      "count": 11,
      "type": "tabak"
    },
    "userObj": {
      "$id": "-KQ52OJd-lwoDIWzfYFT",
      "$priority": null,
      "address": "İzmir kaynaklar",
      "email": "ayse@gmail.com",
      "name": "Ayşe Kahraman",
      "nick": "Ayşe'nin Mutfağı"
    }
  },
  {
    "$id": "-KQlcScsq8cidk7Drs04",
    "userId": "-KQ5-mZBt6MhYy401gGM",
    "title": "Deneme",
    "status": "sale",
    "price": 12,
    "quantity": {
      "count": 10,
      "type": "porsiyon"
    },
    "userObj": {
      "$id": "-KQ5-mZBt6MhYy401gGM",
      "$priority": null,
      "address": "Halkalı küçükçekmece",
      "email": "burak.kahraman@gmail.com",
      "name": "Burak Hero",
      "nick": "Burak'ın Mutfağı"
    }
  },
...
]

相关内容

  • 没有找到相关文章

最新更新