Meteor.js中的应用/用户设置的最佳做法是什么?

我已经看了很多meteor的例子,展示了如何实现应用程序设置和用户特定的设置。 我发现的唯一的东西是Telesc.pe 。 它使用一个Settings集合。 但是,它只有一个全球(意味着每个人都一样)的应用程序设置。

基于这个例子,我创build了自己的settings集合,这个集合在服务器和客户端都可用。

 // Server and Client Settings = new Meteor.Collection('settings'); 

在每个Settingslogging中都有一个userId字段,它等于“默认”或用户的ID。

 { ... userId: 'Default' // <-- 'Default' or Meteor.userId() } 

我有我的发布function发布默认(应用程序)设置和用户的设置。 (注意:在这个应用程序中,每个人都login,不允许客人)

 // Server Meteor.publish('settings', function() { return Settings.find({userId: {$in: [this.userId, 'default']}}); }); 

这里的想法是用户将使用默认设置,直到他们改变设置,从而减less集合中的logging数量。

我也试图抽象出很多繁琐的东西,并创build一些帮助器来获取和设置用户的设置。

 // Server and Client // get user specific settings, fallback to default settings // (not sure if this is the best way, but it works) settings = function() { return Settings.findOne({userId:Meteor.userId()}) || Settings.findOne({userId:'default'}); }; // Get value of a specific setting getSetting = function(key) { return Session.get('settingsLoaded') ? settings()[key] : undefined; }; // Set value of a specific setting setSetting = function(key, value) { // bunch of logic here to see if a user specific record exists // if so, do update // if not, do insert }; 

到目前为止,这个实现似乎工作得很好。 我可以通过m帮助函数设置和获取控制台中的设置。

 // in the console... setSetting('foo', 'bar'); getSetting('foo') // == 'bar' 

我遇到的问题发生在我开始让我的应用根据特定设置采取不同的行为。 例如,我有一个名为“短语”的模板,里面有一个名为“短语”的variables。 我想改变他们如何根据用户的设置sorting。

 Template.phrases.phrases = function () { var sort = {}; var sortKey = getSetting('sortPhrasesBy'); // if I console.log this it is ALWAYS equal to 'title', 'body', or 'date', which is what I want. sort[sortKey] = 1; // returns cursor with all phrases, sorted return Phrases.find({}, {sort:sort}); }; 

除了我不断得到Deps例外,我不能告诉什么是错的。

 Exception from Deps recompute: TypeError: Cannot read property 'nodeName' of null at Patcher.match (http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1540:12) at http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1364:23 at visitNodes (http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1320:11) at visitNodes (http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1321:9) at visitNodes (http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1321:9) at visitNodes (http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1321:9) at visitNodes (http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1321:9) at patch (http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:1334:3) at http://localhost:3000/packages/spark.js?3a050592ceb34d6c585c70f1df11e353610be0ab:698:7 at LiveRange.operate (http://localhost:3000/packages/liverange.js?b3097d72d458e645fd4f0021c8ff5189abe8d98a:491:9) 

我不知道是什么原因造成的。 :/

但是,这个代码实际上工作! 它确实根据用户设置的内容对短语进行sorting。 但是在控制台中,我可以看到每次更改设置都会抛出此exception。 第一次加载是好的。

那么,我在这里做了一些根本性的错误吗? 我必须承认,我还没有把脑袋完全包裹在meteor幕后。

我不知道这是否有用。 但在我尝试实现设置集合之前,我使用了Session对象。 所以我有这样的东西:

 // on client Session.setDefault('sortPhrasesBy', 'title); Template.phrases.phrases = function () { var sort = {}; var sortKey = Session.get('sortPhrasesBy'); sort[sortKey] = 1; // returns cursor with all phrases, sorted a certain way return Phrases.find({}, {sort:sort}); }; 

这工作没有问题。 这不是真正的灵活。

还有另一种方法我应该这样做? 我很想知道,如果有人知道,那些build造meteor的人正在做个人testing/项目的设置。

抱歉这么久的一篇文章,我试图预测什么问题可能会被问及我已经尝试过什么等。

感谢您的任何帮助,您可以提供!

meteor账户系统(例如账户密码)具有内置用户特定设置的概念作为用户对象的“账户”字段。 它是自动发布的,也是react native的(因为Meteor.user()是react native的)。

这里是相关的文档: http : //docs.meteor.com/#meteor_user

关于“nodeName”错误,这是很难debugging,但通常当我得到这个错误是因为我试图访问模板助手,实际上不存在的一部分的DOM。 我也看到了,当我不小心有两个具有相同ID的DOM元素(很容易做到子模板)。

为了追踪它,我删除代码,直到它停止发生,然后将其逐片加回,直到find根本原因。

我为Meteor编写的用户会话智能包对于这个用例来说是非常完美的。

它基本上就像meteorSession ,但每个variables都与用户有关。 它是被动的,所有的变化都是持久的。 它在客户端和服务器上有一个额外的userId参数。

这里的错误看起来像你已经创build了一个服务器端Meteor.publish(),但不是在客户端相应的Meteor.subscribe()。 您正在返回一个空集,并试图更改它的属性。 您可以将订阅放在Deps.autorun块中,或者直接将其包含在帮助器中,如下所示:

 Template.phrases.phrases = function () { var sort = {}; Meteor.subscribe('settings'); var sortKey = getSetting('sortPhrasesBy'); // if I console.log this it is ALWAYS equal to 'title', 'body', or 'date', which is what I want. sort[sortKey] = 1; // returns cursor with all phrases, sorted return Phrases.find({}, {sort:sort}); }; 

你可能会想要使用一个像铁路路由器,它具有挂钩,以确保您的数据加载之前实际上有你的订阅。 看铁路由器 。