1

我有一个 json 集合已上传到我的 firebase,这些站点和工具通过位于前者中的数组相关联,这些数组指向后者中的键

  "sites": {
    "s001": {
      "name": "ACT-105",
      "description": "Intro Accounting",
      "type": "course",
      "thumbnail": "debate",
      "toolCount": 4,
      "tools" : ["t001","t002","t003"]
    },
    "s002": {
      "name": "ART-201",
      "description": "Pottery Lab",
      "type": "course",
      "thumbnail": "sculpture",
      "toolCount": 4,
      "tools" : ["t001","t002","t003","t004"]
    },
  "tools": {
    "t001": {
      "name": "main-tool",
      "title": "Home",
      "description": "Main tool",
      "thumbnail": "home.jpeg"
    },
    "t002": {
      "name": "announce-tool",
      "title": "Announcements",
      "description": "System Announcements",
      "thumbnail": "announcements.jpeg"
    },

我打开一个网址并承诺;然后在一个数组中抓取当前站点及其相关工具数组,然后打开另一个 promise 循环并获取所有相关工具。从警报中,它似乎只抓住一个工具然后退出。

    angular.module("foo", ["firebase"]).
   controller("MyCtrl", ["$scope", "angularFire", function($scope, angularFire) {
  var dbRef = "https://sampledb.firebaseio.com";
  var siteRef = new Firebase(dbRef + "/sites/s003");
  var promise  =  angularFire(siteRef, $scope, "site", {});
  var sitetools = [];
  promise.then(function() {
      sitetools = $scope.site.tools;
      alert("tools " + sitetools);
  }).then(function () {

      var toolList = [];
      for (var i=0;i<sitetools.length;i++)
      {    
          alert("tool " + sitetools[i]);
          toolList.push(getTool(dbRef,toolId));
       }
       $scope.tools = toolList;
  });
  }]);

  var getTool = function(dbRef,toolId) {
  var toolitem;
  var toolRef = new Firebase(dbRef + "/tools/" + toolId);
  alert(toolRef);
  var promise  =  angularFire(toolRef, $scope, "tool", {});
  promise.then(function() {
      alert("found tool " + toolId);
      toolitem = $scope.tool;
  }); 
  return toolitem;
  };

小提琴在这里:http: //jsfiddle.net/5n9mj/1/

4

1 回答 1

5

首先,由于迭代按预期进行,您应该已经收到警报(其中 3 个),但 getTool() 函数的返回始终为 null:它在 promise 解决之前返回,并且本地 tooitem 变量不再可访问.

请记住,所有 Firebase 调用都是异步的。另外,这段代码:

var promise  =  angularFire(toolRef, $scope, "tool", {});
    promise.then(function() {
    alert("found tool " + toolId);
    toolitem = $scope.tool;
}

将触发竞争条件: $scope.tool 与 Firebase 绑定,并且无法保证它会以特定顺序绑定,并且在解决另一个承诺之前是否有足够的处理器时间将其推送到您的数组中。这就是为什么最好使用 Firebase 引用来监听值的变化,而不是使用 angularFire 并将其显式绑定到范围变量。

我认为您使代码有点过于复杂,您不必每次使用 angularFire 绑定范围变量(除非您稍后要使用该引用)时都创建新的 Firebase 引用:angulerFire 可以接受 String url,因为它是第一个参数。

http://jsfiddle.net/oburakevych/5n9mj/10/

如果我是你,我会将 Tool 功能包装到带有单独控制器的指令中,以便每个工具都有自己的范围,如下所示:

<ul ng-repeat="toolId in tools">
    <li><tool tool-id="{{toolId}}"/></li>
</ul>

var promise  =  angularFire(siteRef, $scope, "site", {});
promise.then(function() {
        $scope.broadcast("event:SITE_INITIALIZED");
});

.controller("MyCtrl", ["$scope", "angularFire", '$timeout', function($scope, angularFire, $timeout) {
    $scope.$on("event:SITE_INITIALIZED", function() {
            angularFire(siteRef + "/item/" + $scope.itemId, $scope, "item", {});)
    });
于 2013-08-17T08:23:43.733 回答