[英]What is best practice for app/user settings in Meteor.js?
我已经看了很多关于Meteor的例子,展示了如何实现应用程序设置和用户特定设置。 我发现的唯一一件事就是Telesc.pe 。 它使用一个Settings
集合。 但是,它只有一个全局(对每个人来说都是一样的)app设置。
基于该示例,我创建了自己的settings
集合,可在服务器和客户端上使用。
// Server and Client
Settings = new Meteor.Collection('settings');
在每个Settings
记录中都有一个userId
字段,它等于'Default'或用户的id。
{
...
userId: 'Default' // <-- 'Default' or Meteor.userId()
}
我的发布功能发布了默认(app)设置和用户设置。 (旁注:在这个应用程序中,每个人都登录,不允许任何客人)
// Server
Meteor.publish('settings', function() {
return Settings.find({userId: {$in: [this.userId, 'default']}});
});
这里的想法是用户将使用默认设置,直到他们更改设置,从而减少集合中的记录数。
我还试图抽象出很多繁琐的东西,并创建一些帮助来获取和设置用户的设置。
// 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'
当我开始根据某些设置开始使我的应用采取不同的行为时,我遇到了这个问题。 例如,我有一个名为'phrase'的模板,里面有一个名为'phrase'的变量。 我想根据用户的设置更改它们的排序方式。
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)
我不知道是什么原因引起的。 :/
但是,这段代码确实有效! 它实际上根据用户设置的内容对短语进行排序。 但是在控制台中我可以看到每次更改设置时都会抛出此异常。 第一次加载很好。
那么,我在这里做了一些根本错误的事情吗? 我必须承认,我还没有把头完全缠绕在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});
};
这没有问题。 这不是真正灵活的。
还有另一种方法我应该这样做吗? 如果有人知道的话,我很想知道那些建造流星的人正在做个人测试/项目的设置。
对不起这么长的帖子,我试图预测可能会询问我已经尝试过的问题等等。
感谢您的任何帮助,您可以提供!
Meteor Accounts系统(例如accounts-password)具有用户特定设置的概念,内置为用户对象的“profile”字段。 它会自动发布并且也是被动的(因为Meteor.user()是被动的)。
以下是相关文档: http : //docs.meteor.com/#meteor_user
关于“nodeName”错误,它很难调试,但通常当我得到该错误时,这是因为我试图访问实际上不存在的模板助手中的部分DOM。 当我意外地有两个具有相同ID的DOM元素时(我很容易使用子模板),我也看到了它。
为了追踪它,我删除代码,直到它停止发生,然后逐个添加它,直到我找到根本原因。
我为Meteor编写的用户会话智能包非常适合这种用例。
它基本上类似于Meteor的Session
,但每个变量都与用户有关。 它是被动的,所有的变化都是持久的。 它可以在客户端上使用,也可以在服务器上使用其他userId
参数。
这里的错误看起来像是在客户端创建了服务器端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});
};
您可能希望使用像铁路由器这样的软件包,它具有钩子以确保您在加载数据之前实际拥有订阅。 见铁路由器 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.