Данные пожарной базы нормированы. Как мне получить коллекцию на основе этой структуры?

Я думаю, что приближаюсь, я могу распечатать идентификатор книг, принадлежащих пользователю, но безуспешно пытался получить список книг, принадлежащих пользователю, из справочника книг firebase.

Я следую за этим учебным пособием: http://www.thinkster.io/pick/eHPCs7s87O/angularjs-tutorial-learn-to-rapidly-build-real-time-web-apps-with-firebase#item-526e9330d90f99661f00046c

а также чтение документации о денормализации данных здесь: https://www.firebase.com/blog/2013-04-12-denormalizing-is-normal.html

Как мне это сделать, если я хочу отобразить пользователя на странице, а затем все его книги?

структура firebase

FB
|
--user
| |
| --user1
|   |
|   --name: "test name"
|   --email: "[email protected]"
|   --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" 

Вид

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

контроллер

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

    }]);

Сервис

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

Ответ 1

Начните с обновления до углового Fire 0.6. Это выглядит 0,3. * Ish. angularFire был изменен на $firebase и имеет гораздо более мощный и упрощенный интерфейс.

Vanilla Firebase

Я сделаю это с трудом, так как считаю, что здесь очень важно понять основополагающий принцип. Это довольно сложно, и я только рассмотрю основные вопросы. Существует также множество крошечных случаев:

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

Затем HTML (это будет одинаково для других примеров ниже):

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

Некоторые из краевых случаев, не полностью покрытые здесь:

  • данные не сортируются по приоритету
  • когда запись удаляется из индекса, должен вызывать() по пути данных
  • изменения в упорядочении индекса не изменят порядок записей данных
  • Значение индекса не хранится нигде для ссылки (если это имеет значение)

FirebaseIndex

FirebaseIndex - простая утилита, которая использует индекс, подобный вашему списку книг, и управляет кодом, который мы только что создали выше, более сложным способом.

К сожалению, FirebaseIndex не поддерживает события value, поэтому он не может использоваться с угловым Fire после 0,5.0 из-за изменения внутренних механизмов загрузки в угловом режиме. Так что это не так коротка и сладка, как раньше.

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 - гораздо более мощная и сложная библиотека для нормализации путей. Поскольку он возвращает объект, который работает точно так же, как регулярная ссылка Firebase, он также может быть легко использован с угловымFire 0.5 и выше.

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