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

Dan*_*vin 3 firebase angularfire

我无法从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);
        }
    };
  }
]);
Run Code Online (Sandbox Code Playgroud)

这是我的控制器:

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

这是我的看法:

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

<a class="btn button" ng-href="#!/">Back to Dashboard</a>
Run Code Online (Sandbox Code Playgroud)

我可以提取详细信息项目到路由,但我无法看到任何内容或数据.

Kat*_*ato 9

从语义上讲,此服务创建一个API,该API返回已有的相同方法$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);
});
Run Code Online (Sandbox Code Playgroud)

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

继续讨论按键查找特定记录的问题,可以使用$getRecord阵列上的方法完成.然而,最有可能的是,这不是你想要的.你没有在这里提供用例,这对于我们如何处理你的预期设计非常有限(参见XY问题),但是你的代码建议你只需要一条记录而不是数组.这应该使用$firebaseObject而不是尝试同步列表,然后从列表中提取单个项目来完成:

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

现在可以简单地获取表示任何记录的synchronized对象,如下所示:

app.controller('...', function(Record) {
   var rec = Record( 'foobar123' );
});
Run Code Online (Sandbox Code Playgroud)

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

<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>
Run Code Online (Sandbox Code Playgroud)

和控制器:

$scope.list = $firebaseArray(...);
$scope.pickItem = function(rec) {
  $scope.selectedRec = rec;
};
Run Code Online (Sandbox Code Playgroud)