火力地堡数据标准化。我应该如何获取基于此结构的集合? [英] Firebase data normalized. How should I fetch a collection based on this structure?

查看:226
本文介绍了火力地堡数据标准化。我应该如何获取基于此结构的集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得我越来越近,我能打印出属于用户的书籍ID,但一直在努力失败获取属于用户书籍列表,从火力书籍参考。

我在这里下松散教程:
<一href=\"http://www.thinkster.io/pick/eHPCs7s87O/angularjs-tutorial-learn-to-rapidly-build-real-time-web-apps-with-firebase#item-526e9330d90f99661f00046c\">http://www.thinkster.io/pick/eHPCs7s87O/angularjs-tutorial-learn-to-rapidly-build-real-time-web-apps-with-firebase#item-526e9330d90f99661f00046c

和阅读也是这里非规范化的数据文档:
<一href=\"https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html\">https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html

我应该如何去了解它,如果我想显示在页面的用户,其次是它的所有书籍?

火力结构

  FB
|
- 用户
| |
| --user1
| |
| --name:测试名称
| --email:test@test.com
| - 图书
| |
| -JFZG3coHOAblHZ7XSjK:真
| -KJKJASDIUOPIWE9WEeJ​​:真
| -YtUTRGJLNL876F3SSwS:真
|
- 图书
  |
   - - JFZG3coHOAblHZ7XSjK
  | |
  | --title:书名1
  | --ownerId:USER1
  |
   - - KJKJASDIUOPIWE9WEeJ
  | |
  | --title:书名2
  | --ownerId:USER1
  |
   - - YtUTRGJLNL876F3SSwS
  | |
  | --title:书名2
  | --ownerId:USER1

查看

 &LT; D​​IV数据-NG-控制器=UsersController数据-NG-的init =findOneUser()&GT;
  &LT; H2&GT;简介&LT; / H&GT;
  &LT; IMG类=image_ preVIEW数据-NG-SRC ={{user.photoUrl}}&GT;
  &LT; P&GT;名称:{{user.name}}&LT; / P&GT;
  &所述p为H.;名称:{{user.email}}&下; / P&GT;
  &LT;数据-NG-HREF =#/用户/ {{用户id}} /编辑&gt;编辑&LT; / A&GT;  &LT; H2&GT;混合咖啡&LT; / H&GT;  &LT; D​​IV数据-NG-重复=书user.books&GT;
    &所述p为H.; ---&下; / P&GT;
    &所述p为H.; {{user.books}}&下; / P&GT;
  &LT; / DIV&GT;
  &所述;! - &下;格数据纳克控制器=BooksController中数据的init =&GT - →;  &LT;! - &LT; / DIV&GT; - &GT;
&LT; / DIV&GT;

控制器

 使用严格的;angular.module('ccApp.controllers.users',['ccApp.services.users'])
    .controller('UsersController',['$范围,$ routeParams','$的位置,angularFire','用户',
      功能($范围,$ routeParams,$位置,angularFire,用户){      $ scope.user = {};
      $ scope.userId = $ routeParams.userId;      $ scope.findOneUser =功能(用户id){
        如果(!! $ scope.userId){
          angularFire(Users.find($ routeParams.userId),$范围,用户);
        }
      };      $ scope.updatePhotoUrl =功能(URL,用户){
        $ scope.fileUrl =网址;
        的console.log($ scope.fileUrl [0] .URL);
        user.photoUrl = $ scope.fileUrl [0] .URL;
      };      $ scope.findUsers =功能(){
        $ scope.users = Users.collection();
      };      $ scope.findWholesalers =功能(){
        $ scope.wholesalers = Users.collection();
      };    }]);

服务

 使用严格的;angular.module('ccApp.services.users',['ccApp.services.firebaseRefs'])
  .factory('用户',['angularFireCollection','FireRef',
    功能(angularFireCollection,FireRef){
      返回{
        集合:函数(CB){
          返回angularFireCollection(FireRef.users(),CB);
        }
      ,发现:功能(用户id){
          返回FireRef.users()子('/'+用户id)。
        }
      };
  }]);


解决方案

通过更新到0.6 angularFire开始。这看起来0.3。*十岁上下。 angularFire已更改为 $火力并拥有更强大和简化的界面。

香草火力地堡

我认为在这里认识的基本原则巨大的价值,我会这样先做艰辛的道路。这是相当复杂的,而且我将只涵盖必需品。有很多微小的边缘督办案件,以及:

  angular.module(应用,[])
    .controller('UsersController',函数($范围,$火力点,$超时,$ routeParams){
      VAR用户id = $ routeParams.userId;
      $ scope.user = $火力点(新火力地堡(URL /用户/+用户id));      //或者3双向绑定,自动写回火力地堡
      VAR userRef = $火力点(新火力地堡(URL /用户/+用户id))$绑定($范围用户)。      //使用火力地堡(艰难地)抓住这个用户书
      $ scope.books = {};
      VAR booksRef =新的火力地堡(URL /书籍/');      //获取用户的图书列表动态地,因为它可以以实时改变
      VAR indexRef =新的火力地堡(URL /用户/+用户id +'/书');      //看指数添加事件
      indexRef.on('child_added',函数(indexSnap){
         //把书取来,放入我们的名单
         变种BOOKID = indexSnap.name();
         booksRef.child(BOOKID)。在(价值,功能(bookSnap){
            //触发消化$ / $应用使角同步的DOM
            $超时(函数(){
               如果(snap.val()=== NULL){
                  //这本书已被删除
                  删除$ scope.books [BOOKID]
               }
               其他{
                  $ scope.books [BOOKID] = snap.val();
               }
            });
         });
      });      //观看删除事件的索引
      indexRef.on('child_removed',函数(SNAP){
         //触发消化$ / $应用使角更新DOM
         $超时(功能(SNAP){
            删除$ scope.books [snap.name()];
         });
      });
});

然后,HTML(这将是相同的为低于其它实施例):

 &LT; D​​IV数据-NG-重复=(BOOKID,书籍)的书籍&GT;
   {{BOOKID}}:{{book.title}}
&LT; / DIV&GT;

一些边缘的情况下,不能在这里全面覆盖:


  • 数据不是按优先顺序进行排序

  • 当记录从索引中被删除,应该在数据路径叫停()

  • 在该指数的排序变化不会改变的数据记录顺序

  • 的索引值不存储,以供参考(如果它事项)

FirebaseIndex

FirebaseIndex 是一个简单的工具,需要一个指数喜欢你的书单和管理,我们在上面刚刚创建的code多一点复杂的方式。

不幸的是,FirebaseIndex不支持事件,所以它不能与angularFire 0.5.0后使用,因为更改angularFire内部装载机制。因此,这不是很简短而亲切,因为它曾经是。

  angular.module(应用,[])
.controller('UsersController',函数($范围,$火力点,$超时){
   VAR用户id = $ routeParams.userId;
   $ scope.user = $火力点(新火力地堡(URL /用户/+用户id));   变种FB =新的火力地堡(URL);
   VAR指数=新FirebaseIndex(fb.child('用户名/'+用户id +'/书籍'));
   $ scope.books = {};   //几乎魔术
   index.on('child_added',函数(SNAP){
      $超时(函数(){$ scope.books [snap.name()] = snap.val();});
   });   index.on('child_removed',函数(SNAP){
      $超时(函数(){$删除scope.books [snap.name();});
   });
});

Firebase.util.join

火力地堡-UTIL 是正常化的路径更加强大和复杂的图书馆。因为它返回的作品就像一个普通的火力地堡引用一个对象,它也可以无缝地与上述angularFire 0.5和使用。

  angular.module(应用,[])
.controller('UsersController',函数($范围,$火力点){
   VAR用户id = $ routeParams.userId;
   $ scope.user = $火力点(新火力地堡(URL /用户/+用户id));   变种FB =新的火力地堡(URL);
   VAR REF =新Firebase.util.intersection(fb.child('用户名/'+用户id +'/书),fb.child('书'));   // 魔法!
   $ scope.books = $火力点(REF);
});

I think I am getting close, I am able to print out the ID of books belonging to a user but have been trying unsuccessfully to fetch the list of books belonging to a user, from the firebase books reference.

I'm following loosely the tutorial here: http://www.thinkster.io/pick/eHPCs7s87O/angularjs-tutorial-learn-to-rapidly-build-real-time-web-apps-with-firebase#item-526e9330d90f99661f00046c

and also reading the documentation about denormalizing data here: https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html

How should I go about it if I want to display the user in a page, followed by all its books?

firebase structure

FB
|
--user
| |
| --user1
|   |
|   --name: "test name"
|   --email: "test@test.com"
|   --books
|     |
|     "-JFZG3coHOAblHZ7XSjK": true
|     "-KJKJASDIUOPIWE9WEeJ": true
|     "-YtUTRGJLNL876F3SSwS": true
|
--books
  |
  --"-JFZG3coHOAblHZ7XSjK"
  | |
  | --title: "book title 1"
  | --ownerId: "user1"
  |
  --"-KJKJASDIUOPIWE9WEeJ"
  |  |
  |  --title: "book title 2"
  |  --ownerId: "user1" 
  |    
  --"-YtUTRGJLNL876F3SSwS"
  |  |
  |  --title: "book title 2"
  |  --ownerId: "user1" 

View

<div data-ng-controller="UsersController" data-ng-init="findOneUser()">
  <h2>Profile</h2>
  <img class="image_preview" data-ng-src="{{user.photoUrl}}">
  <p>Name: {{ user.name }}</p>
  <p>Name: {{ user.email }}</p>
  <a data-ng-href="#/users/{{ userId }}/edit">Edit</a>

  <h2>Coffee Blends</h2>

  <div data-ng-repeat="book in user.books">
    <p>---</p>
    <p>{{user.books}}</p>
  </div>
  <!--<div data-ng-controller="BooksController" data-init="">-->

  <!--</div>-->
</div>

Controller

'use strict';

angular.module('ccApp.controllers.users', ['ccApp.services.users'])
    .controller('UsersController', ['$scope', '$routeParams', '$location', 'angularFire', 'Users',
      function($scope, $routeParams, $location, angularFire, Users){

      $scope.user = {};
      $scope.userId = $routeParams.userId;

      $scope.findOneUser = function(userId){
        if (!!$scope.userId){
          angularFire(Users.find($routeParams.userId), $scope, 'user');
        }
      };

      $scope.updatePhotoUrl = function(url, user){
        $scope.fileUrl = url;
        console.log($scope.fileUrl[0].url);
        user.photoUrl = $scope.fileUrl[0].url;
      };

      $scope.findUsers = function(){
        $scope.users = Users.collection();
      };

      $scope.findWholesalers = function(){
        $scope.wholesalers = Users.collection();
      };

    }]);

Service

'use strict';

angular.module('ccApp.services.users', ['ccApp.services.firebaseRefs'])
  .factory('Users', ['angularFireCollection', 'FireRef',
    function(angularFireCollection, FireRef){
      return{
        collection: function(cb){
          return angularFireCollection(FireRef.users(), cb);
        }
      , find: function(userId){
          return FireRef.users().child('/'+userId);
        }
      };
  }]);

解决方案

Begin by updating to angularFire 0.6. This looks 0.3.*ish. angularFire has been changed to $firebase and has a much more powerful and simplified interface.

Vanilla Firebase

I'll do this the hard way first as I think there is great value in understanding the underlying principle here. It's fairly complex, and I'll only cover the essentials. There are a lot of tiny edge cases to be handled as well:

angular.module('app', [])
    .controller('UsersController', function($scope, $firebase, $timeout, $routeParams){
      var userId = $routeParams.userId;
      $scope.user = $firebase(new Firebase('URL/user/'+userId));

      // or, for 3-way binding and automatic writes back to Firebase
      var userRef = $firebase(new Firebase('URL/users/'+userId)).$bind($scope. 'user');

      // grab this users' books using Firebase (the hard way)
      $scope.books = {};
      var booksRef = new Firebase('URL/books/');

      // fetch the user's book list dynamically because it may change in real-time
      var indexRef = new Firebase('URL/user/'+userId+'/books');

      // watch the index for add events
      indexRef.on('child_added', function(indexSnap) {
         // fetch the book and put it into our list
         var bookId = indexSnap.name();
         booksRef.child(bookId).on('value', function(bookSnap) {
            // trigger $digest/$apply so Angular syncs the DOM
            $timeout(function() {
               if( snap.val() === null ) {
                  // the book was deleted
                  delete $scope.books[bookId];
               }
               else {
                  $scope.books[bookId] = snap.val();
               }
            });
         });
      });

      // watch the index for remove events
      indexRef.on('child_removed', function(snap) {
         // trigger $digest/$apply so Angular updates the DOM
         $timeout(function(snap) {
            delete $scope.books[snap.name()];
         });
      });
});

Then the HTML (this will be the same for the other examples below):

<div data-ng-repeat="(bookId, book) in books">
   {{bookId}}: {{book.title}}
</div>

Some of the edge cases not fully covered here:

  • data is not sorted by priority ordering
  • when a record is deleted from index, should call off() on data paths
  • changes in ordering of the index won't change order of data records
  • value of the index is not stored anywhere for reference (if it matters)

FirebaseIndex

FirebaseIndex is a simple utility that takes an index like your book list and manages the code we just created above in a bit more sophisticated manner.

Unfortunately, FirebaseIndex doesn't support value events, so it can't be used with angularFire after 0.5.0 because of a change to angularFire's internal loading mechanisms. So it's not quite as short and sweet as it used to be.

angular.module('app', [])
.controller('UsersController', function($scope, $firebase, $timeout){
   var userId = $routeParams.userId;
   $scope.user = $firebase(new Firebase('URL/user/'+userId));

   var fb = new Firebase(URL);
   var index = new FirebaseIndex( fb.child('user/'+userId+'/books') );
   $scope.books = {};

   // almost magic
   index.on('child_added', function(snap) {
      $timeout(function() { $scope.books[snap.name()] = snap.val(); });
   });

   index.on('child_removed', function(snap) {
      $timeout(function() { delete $scope.books[snap.name()]; });
   });
});

Firebase.util.join

Firebase-util is a much more powerful and sophisticated library for normalizing paths. Because it returns an object that works just like a regular Firebase reference, it can also be used seamlessly with angularFire 0.5 and above.

angular.module('app', [])
.controller('UsersController', function($scope, $firebase){
   var userId = $routeParams.userId;
   $scope.user = $firebase(new Firebase('URL/user/'+userId)); 

   var fb = new Firebase(URL);
   var ref = new Firebase.util.intersection( fb.child('user/'+userId+'/books'), fb.child('books') );

   // magic!
   $scope.books = $firebase(ref);
});

这篇关于火力地堡数据标准化。我应该如何获取基于此结构的集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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