如何从与 Firebase 同步的 AngularFire 集合中获取单个记录 [英] How can I get a single record from AngularFire collection synchronized from Firebase

查看:32
本文介绍了如何从与 Firebase 同步的 AngularFire 集合中获取单个记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是我的服务:

app.factory("Projects", ["$firebaseArray", function($firebaseArray) {//创建对 Firebase 的引用,我们将在其中存储我们的数据var ref = new Firebase("https://XXXXXXXXXX.firebaseio.com");var childRef = ref.child('projects');var 项目 = $firebaseArray(childRef);返回 {所有:项目,创建:功能(项目){返回项目.$add(project);},得到:函数(projectId){控制台日志(projectId);project.$loaded().then(function(x) {var project = x.$getRecord(projectId);控制台日志(项目);//这个打印空}).catch(函数(错误){console.log("错误:", 错误);});},删除:功能(项目){返回项目.$remove(project);}};}]);

这是我的控制器:

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

这是我的观点:

<p>{{project.creatorUID}}</p><p>项目 ID:{{project.$id}}</p>

<a class="btn button" ng-href="#!/">返回仪表板</a>

就路由而言,我可以调出详细项目,但看不到任何内容或数据.

解决方案

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

app.factory("Projects", function($firebaseArray) {//创建对 Firebase 的引用,我们将在其中存储我们的数据var ref = new Firebase("https://XXXXXXXXXX.firebaseio.com").child('projects');返回 $firebaseArray(ref);});

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

转到有关通过键查找特定记录的问题,这可以使用数组上的 $getRecord 方法来完成.然而,这很可能不是您要找的.您尚未在此处提供用例,这对于我们解决您的预期设计的能力非常有限(请参阅 XY 问题),但您的代码表明您只需要一个记录而不是数组.这应该使用 $firebaseObject 来完成,而不是尝试同步列表然后从列表中提取单个项目:

app.factory('Record', function($firebaseObject) {var baseRef = new Firebase('...').child('projects');返回函数(记录 ID){返回 $firebaseObject(baseRef.child(recordId));}});

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

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

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

    <li ng-repeat="rec in list">{{rec.$id}}:{{rec.name}}<button ng-click="pickItem(rec)">选择</button>
<form ng-show="selectedRec"><input ng-model="selectedRec.field"ng-change="list.$save(selectedRec)"/></表单>

和控制器:

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

I am having trouble getting a single record from an AngularFire synchronized array.

This is my service:

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);
        }
    };
  }
]);

This is my controller:

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

This is my view:

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

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

I can pull up the detail project as far as the routing but I am not able to see any content or data.

解决方案

Semantically speaking, this service creates an API that returns the same methods already available on $firebaseArray. There's really no need for this service at all as it provides no additional functionality and does not abstract any complexity. It could easily be reduced to:

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);
});

Since the methods already call $add, $delete, et al internally, those can be used by the callee in place of the wrapping methods.

Moving on to the question about finding a specific record by key, this can be done using the $getRecord method on the array. Most likely, however, this isn't what you're looking for. You haven't provided the use case here, which is pretty limiting for how well we can address your intended design (see XY problem), but your code suggests you just want one record and not the array. This should be done using $firebaseObject rather than trying to synchronize a list and then extract a single item from the list:

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

Now one can simply fetch the synchronized object representing any record like so:

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

Another common use case is creating a list where you click an item, and then edit the contents for that specific item, and save them back to Firebase (i.e. some sort of editable grid/list view). That can already be done without any unnatural and duplicate synchronization of content already in the array:

<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>

And the controller:

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

这篇关于如何从与 Firebase 同步的 AngularFire 集合中获取单个记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆