加入一个值/键AngularFire路径不工作(合并用户配置文件为记录) [英] Joining AngularFire paths on a value/key is not working (merging user profiles into records)

查看:257
本文介绍了加入一个值/键AngularFire路径不工作(合并用户配置文件为记录)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发展与火力地堡的应用程序(1.0)和角度(1.4)。我遇到的问题是确保鉴于与火力地堡同步的数据,而获取数据denormalised两个表进来的火力地堡:

I am developing an application with Firebase (1.0) and Angular (1.4). The problem I'm having is to ensure the data in view are synchronised with Firebase, while fetching denormalised data coming from two tables in Firebase:

这本书表如下所示:
    

The book table looks like this:


books:
    -JyDpkQrUozE3L7flpo: {
    title: "title1",
    author: {-JyDpkQrUozE3L7fl1x: true}
    },
    -JyDpkQrUozE3L7flp1: {
    title: "title2",
    author: {-JyDptrrrezE3L7flKx: true}
    },
    -JyDpkQrUozE3L7flp2: {
    title: "title3",
    author: {-JyDpkQrUozE3L7f222: true}
    }
    

笔者表如下所示:
    

The author table looks like this:


authors:
    -JyDpkQrUozE3L7flKx: {
        firstname: "jacques",
        lastname: "smith"
    },
    -JyDptrrrezE3L7flKx: {
        firstname: "bill",
        lastname: "halley"
    },
    -JyDpkQrUozE3L7f222: {
        firstname: "john",
        lastname: "ford"
    }
    

我的控制器看起来是这样的:
    

My controller looks like this:


.controller('booksController', ['$scope', '$firebaseArray', function($scope, $firebaseArray) {
     var ref = new Firebase("https://[PATH].firebaseio.com/";
     $scope.bookList = $firebaseArray(ref.child('books'));
     $scope.authorList = $firebaseArray(ref.child('authors'));
     $scope.getAuthor = function(id) {
        return $scope.authorList.$getRecord(id);
    };
});
    

和我的HTML看起来像这样:

And my html looks like this:

<pre>
<p ng-repeat="book in books" ng-init="author = getAuthor(book.author)">
The author of {{book.title}} is {{author.firstName}} {{author.lastName}}.
</p>
</pre>

以上所需的输出应该是:TITLE1的作者是雅克·史密斯TITLE2的作者是比尔哈雷......。然而,什么我得到的是:。标题1的作者是TITLE2的作者是......于是,笔者在我的HTML返回空白

The desired output of the above should be: "The author of title1 is Jacques Smith. The author of title2 is Bill Halley ...". What I'm getting however is: "The author of title 1 is. The author of title2 is..." So the author in my html returns a blank.

任何想法?

推荐答案

布兰登的答案是技术上正确答案提出的问题。我要阐述了一下什么会是一个更好的方式加入这些记录。

Brandon's answer is technically-correct answer to the posed question. I'm going to elaborate a bit on what would be a better way to join these records.

其实我已经在小提琴回答这个确切的问题,并且还提供了一个更复杂的, 如何缓存和合并用户配置文件为对象。我要重申的是如何在这里工作的细节。

I've actually answered this exact question in a fiddle, and also provided a more sophisticated, elegant, and simpler solution of how to cache and merge user profiles into objects. I'll reiterate the details of how this works here.

app.factory('NormalizedPosts', function($firebaseArray, userCache) {
  var PostsWithUsers = $firebaseArray.$extend({

   // override $$added to include users
   $$added: function(snap) {
       // call the super method
       var record = $firebaseArray.prototype.$$added.call(this, snap);
       userCache.$load( record.user ).$loaded(function( userData ) {
            record.userData = userData;
       });
       // return the modified record
       return record;
   }

  });
  return PostsWithUsers;
});

在这里,我已经决定要使用用户的缓存列表,因为他们很可能是高度冗余的,这提供了一个优雅的方式来保持同步的一切。这不是绝对必要的 - 我们可以看看它们就在那里$$增加,但留下一些边督办案件。所以,同步用户的缓存,感觉就在这里。

Here I've decided to use a cached list of users, since they are likely to be highly redundant, and this provides an elegant way to keep everything in sync. It's not strictly necessary--we could look them up right there in $$added, but that leaves some edge cases to be handled. So a cache of synchronized users feels right here.

因此​​,这里的缓存实用程序:

So here's the caching utility:

app.factory('userCache', function ($firebase) {
    return function (ref) {
        var cachedUsers = {};
        // loads one user into the local cache, you do not need to
        // wait for this to show it in your view, Angular and Firebase
        // will work out the details in the background
        cachedUsers.$load = function (id) {
            if( !cachedUsers.hasOwnProperty(id) ) {
                cachedUsers[id] = $firebaseObject(ref.child(id));
            }
            return cachedUsers[id];
        };
        // frees memory and stops listening on user objects
        // use this when you switch views in your SPA and no longer
        // need this list
        cachedUsers.$dispose = function () {
            angular.forEach(cachedUsers, function (user) {
                user.$destroy();
            });
        };
        // removes one user, note that the user does not have
        // to be cached locally for this to work
        cachedUsers.$remove = function(id) {
            delete cachedUsers[id];
            ref.child(id).remove();
        };
        return cachedUsers;
    }
});

和这里的一个要点把他们放在一起

请注意,如果我们知道,当我们的控制器被破坏,该数据将不再是有益的,我们可以通过调用清理听众和内存 $摧毁 。这不是绝对必要的,并可能是一个premature优化,但可能是值得一提,可与具有记录成千上万跟踪复杂的生产应用程序的用户:

Note that, if we know that when our controller is destroyed, that the data will no longer be useful, we can clean up the listeners and memory by calling $destroy. This isn't strictly necessary and could be a premature optimization, but is probably worth mentioning for users with complex production apps that have tens of thousands of records to track:

app.controller('...', function(NormalizedPosts, userCache, $scope) {
   $scope.posts = new NormalizedPosts(<firebase ref>);
   $scope.$on('$destroy', function() {
      $scope.posts.$destroy();
      userCache.$dispose();
   });
});

这篇关于加入一个值/键AngularFire路径不工作(合并用户配置文件为记录)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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