Fetching item by unique firebase id in angularfire 1.0.0
我无法使用 angularfire 1.0.0 从我的 Firebase 中获取一件独特的物品。澄清一下,我希望我的应用能够获取给定唯一 Firebase id 的帖子,例如"-JkZwz-tyYoRLoRqlI_I"。它在应用程序中导航时有效,例如单击指向特定帖子的链接,但不单击刷新。我的猜测是它与同步有关。现在它在获取所有帖子并在 ng-repeat 中使用它时工作。这是导航到页面时为什么它适用于一个项目的线索。这可能不难,因为这应该是一个非常标准的操作,但我无法让它工作。我到处搜索,但实际上没有这方面的指南。在 API 中,它们指的是
Returns the record from the array for the given key. If the key is not
found, returns null. This method utilizes $indexFor(key) to find the
appropriate record.
但这并没有按预期工作。还是我错过了什么?
它适用于 ng-repeat,如下所示:
1 2 3 | {{postt.title}} {{postt.timestamp}} {{postt.content}} |
但不适用于像这样的独特物品:
1 2 3 | {{post.title}} {{post.timestamp}} {{post.content}} |
这是服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 'use strict'; angular.module('app.module.blog.post') .factory("PostService", ["$firebaseArray","FIREBASE_URL", function($firebaseArray, FIREBASE_URL) { var ref = new Firebase(FIREBASE_URL +"posts"); var posts = $firebaseArray(ref); return { all: posts, // ng-repeat on this works fine last: function(nr) { var query = ref.orderByChild("timestamp").limitToLast(nr); return $firebaseArray(query); // ng-repeat on this work fine to }, create: function (post) { return posts.$add(post); }, get: function (postId) { console.log(postId); // This is -JkZwz-tyYoRLoRqlI_I var post = posts.$getRecord(postId); console.log(post); // This print null return post; }, delete: function (post) { return posts.$remove(post); } }; }]); |
正如评论在get函数中所说,postId在那里并且posts也被设置了,但是post是null。
这是控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 | 'use strict'; angular.module('app.module.blog.post', []) .controller('PostCtrl', ['$scope', '$routeParams', 'PostService', function($scope, $routeParams, PostService) { // This returns e.g. postId"-JkZwz-tyYoRLoRqlI_I" console.log($routeParams.postId); $scope.post = PostService.get($routeParams.postId); $scope.posts = PostService.all; // Illustrates the example not actually in this controller otherwise }]); |
这是关于 firebase 数据库中内容的示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <myfirebase> posts -JkUnVsGnCqbAxbMailo comments content: ... timestamp: ... title: ... -JkZwz-tyYoRLoRqlI_I comments content: ... timestamp: ... title: ... -JkhaEf9tQy06cOF03Ts content: ... timestamp: ... title: ... |
我觉得这个问题很奇怪,因为它应该很标准。我显然错过了一些东西,但无法解决。非常感谢任何帮助!
提前致谢!
我知道 $getRecord() 函数的文档有点误导。您实际上从
1 2 3 4 5 6 7 | var posts = $firebaseArray(ref); posts.$loaded().then(function(x) { var post = x.$getRecord(postId); console.log(post); }).catch(function(error) { console.log("Error:", error); }); |
如果你想知道为什么它适用于
这是由于Promise而发生的。
-
正如加藤所说,Jean-Philippe 说,
$firebaseArray 不是立即可用的,因为它需要下载。 -
请参阅
.$loaded() 文档:.$loaded() "returns a promise which is resolved when the initial array data has been downloaded from Firebase. The promise resolves to the $firebaseArray itself."
这回答了你的问题,我只是想展示另一种方法:
-
这是扩展 AngularFire 服务的一个很好的用例。
-
正如 AngularFire API 文档所说:
"There are several powerful techniques for transforming the data downloaded and saved by
$firebaseArray and$firebaseObject . These techniques should only be attempted by advanced Angular users who know their way around the code."
-
正如 AngularFire API 文档所说:
-
将所有这些放在一起,您可以通过以下方式完成您想做的事情:
-
扩展 Firebase 服务
$firebaseArray - 遵循扩展服务的文档。
-
扩展 Firebase 服务
例子
- 这是我放在一起的一个有效的 JSFIDDLE 示例,它与我的一个公共 Firebase 实例相关联。
-
请务必注意,您应该将
".indexOn":"timestamp" 添加到/posts 的规则中。
工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | app.factory('PostsArray', function (FBURL, PostsArrayFactory) { return function (limitToLast) { if (!limitToLast) { console.error("Need limitToLast"); return null; } var postsRef = new Firebase(FBURL + '/posts').orderByChild('timestamp').limitToLast(limitToLast); return new PostsArrayFactory(postsRef); } }); app.factory('PostsArrayFactory', function ($q, $firebaseArray) { return $firebaseArray.$extend({ getPost: function (postKey) { var deferred = $q.defer(); var post = this.$getRecord(postKey); if (post) { console.log("Got post", post); deferred.resolve(post); } else { deferred.reject("Post with key:" + postKey +" not found."); } return deferred.promise; }, createPost: function (post) { var deferred = $q.defer(); post.timestamp = Firebase.ServerValue.TIMEST this.$add(post).then(function (ref) { var id = ref.key(); console.log("added post with id", id,"post:", post); deferred.resolve(ref); }). catch (function (error) { deferred.reject(error); }); return deferred.promise; } }); }); |
控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | app.controller("SampleController", function ($scope, PostsArray) { var posts = new PostsArray(5); $scope.posts = posts; $scope.newPost = {}; $scope.createNewPost = function () { posts.createPost($scope.newPost); } $scope.postId = ''; $scope.getPost = function () { posts.getPost($scope.postId).then(function (post) { $scope.gotPost = post; }). catch (function (error) { $scope.gotPost = error; }); } }); |