How to load the (n> 2) level of nested data from a denormalized dataset using Firebase / AngularFire?

Given a denormalized data structure, for example:

{
  "users" : {
    "-JMMXslDJkPYmgcwXUzP" : {
      "items" : [ "-JMMXYaWlg_ftL2sKsdp", ... ],
      "name" : "user0"
    },
    ...
  },
  "items" : {
    "-JMMXYac7EMZcr4LIL5u" : {
      "properties" : [ "-JMMWdpWig-L8oIqbeI1", ... ],
      "name" : "item0"
    },
    ...
  },
  "properties" : {
    "-JMMWdpe3WEyjnUM12o2" : {"name": "property0"},
    ...
  }
}

I am currently loading nested children as follows:

<ul ng-init="users = $ref('users')">
    <li ng-repeat="user in users">
        <h1>{{ user.name }}</h1>
        <ul>
            <li ng-repeat="item_id in user.items" ng-init="item = $ref('items/'+item_id)">
                <h2>{{ item.name }}</h2>
                <ul>
                    <li ng-repeat="property_id in item.properties" ng-init="property = $ref('properties/'+property_id)">
                        <h3>{{ property.name}}</h3>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

Here plunker shows how unbearably slow loading becomes with only 3 levels of deep nested data: http://plnkr.co/edit/yrRx2FYJEc5BM1MaSQDe?p=preview

How to speed up loading / rendering of this data?

  • Please note that the solution posted here (creating one link for each collection instead of each item in the collection) will not work for me, since all / all of my sub-collections will be too large.
+4
1

. , - , ng-repeat , . .

, , . , ; :

:

<li ng-repeat="user in users" ng-init="item = items.$load(user.item_id)">
    {{user.name}}: {{item.name}}
</li>

:

// CONTROLLER

app.controller('ctrl', function ($scope, $firebase, itemCache) {
    $scope.users = $firebase(fb.child('users'));
    $scope.items = itemCache(fb.child('items'));
    $scope.$on('$destroy', $scope.items.$dispose);
});

app.factory('itemCache', function ($firebase) {
    return function (ref) {
        var cachedItems = {};
        cachedItems.$load = function (id) {
            if( !cachedItems.hasOwnProperty(id) ) {
                cachedItems[id] = $firebase(ref.child(id));
            }
            return cachedItems[id];
        };
        cachedItems.$dispose = function () {
            angular.forEach(cachedItems, function (item) {
                item.$off();
            });
        };
        return cachedItems;
    }
});
+4

Source: https://habr.com/ru/post/1539632/


All Articles