如何从从 Firebase 同步的 AngularFire 集合中获取单个记录

How can I get a single record from AngularFire collection synchronized from Firebase

我无法从 AngularFire 同步数组中获取单个记录。

这是我的服务:

app.factory("Projects", ["$firebaseArray", function($firebaseArray) {
    // create a reference to the Firebase where we will store our data
    var ref = new Firebase("https://XXXXXXXXXX.firebaseio.com");
    var childRef = ref.child('projects');
    var projects = $firebaseArray(childRef);

    return {
        all: projects,

        create: function (projects) {
            return projects.$add(project);
        },
        get: function (projectId) {
            console.log(projectId);
            projects.$loaded().then(function(x) {
                var project = x.$getRecord(projectId);
                console.log(project); // This print null
            }).catch(function(error) {
                console.log("Error:", error);
            });
        },
        delete: function (project) {
            return projects.$remove(project);
        }
    };
  }
]);

这是我的控制器:

app.controller('ProjectViewCtrl', function ($scope, $routeParams, Projects, Auth) {
    $scope.project = Projects.get($routeParams.projectId);
});

这是我的观点:

<div>
 <p>{{project.creatorUID}}</p>
 <p>Project ID: {{project.$id}}</p>
</div>

<a class="btn button" ng-href="#!/">Back to Dashboard</a>

我可以拉出详细项目到路由,但我看不到任何内容或数据。

从语义上讲,此服务创建了一个 API returns $firebaseArray 上已经可用的相同方法。确实根本不需要此服务,因为它不提供额外的功能,也不抽象任何复杂性。它可以很容易地简化为:

app.factory("Projects", function($firebaseArray) {
    // create a reference to the Firebase where we will store our data
    var ref = new Firebase("https://XXXXXXXXXX.firebaseio.com").child('projects');
    return $firebaseArray(ref);
});

由于这些方法已经在内部调用了 $add、$delete 等,因此被调用者可以使用这些方法来代替包装方法。

继续讨论通过键查找特定记录的问题,这可以使用数组上的 $getRecord 方法来完成。然而,这很可能不是您要查找的内容。您没有在此处提供用例,这非常限制了我们如何很好地解决您的预期设计(请参阅 XY problem),但您的代码表明您只需要一个记录而不是数组。这应该使用 $firebaseObject 而不是尝试同步列表然后从列表中提取单个项目来完成:

app.factory('Record', function($firebaseObject) {
   var baseRef = new Firebase('...').child('projects');
   return function(recordId) {
      return $firebaseObject(baseRef.child(recordId));
   }
});

现在可以像这样简单地获取表示任何记录的同步对象:

app.controller('...', function(Record) {
   var rec = Record( 'foobar123' );
});

另一个常见用例是创建一个列表,您可以在其中单击一个项目,然后编辑该特定项目的内容,并将它们保存回 Firebase(即某种可编辑的 grid/list 视图)。这已经可以在数组中没有任何不自然和重复的内容同步的情况下完成:

<ul>
  <li ng-repeat="rec in list">
     {{rec.$id}}: {{rec.name}}
     <button ng-click="pickItem(rec)">select</button>
  </li>
</ul>

<form ng-show="selectedRec">
  <input ng-model="selectedRec.field" 
         ng-change="list.$save(selectedRec)" />
</form>

控制器:

$scope.list = $firebaseArray(...);
$scope.pickItem = function(rec) {
  $scope.selectedRec = rec;
};