Meteor.js中应用程序/用户设置的最佳实践是什么
What is best practice for app/user settings in Meteor.js?
我看了很多Meteor的例子,展示了如何实现应用程序设置和用户特定设置。我唯一找到的是Telesc.pe。它使用了Settings
集合。然而,它只有一个全局(对每个人来说都是一样的)应用程序设置。
在该示例的基础上,我创建了自己的settings
集合,该集合在服务器和客户端上都可用。
// Server and Client
Settings = new Meteor.Collection('settings');
在每个Settings
记录中都有一个userId
字段,该字段等于"默认"或用户id。
{
...
userId: 'Default' // <-- 'Default' or Meteor.userId()
}
我的发布功能同时发布默认(应用程序)设置和用户设置。(附带说明:在此应用程序中,所有人都已登录,不允许访客)
// 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'
当我开始让我的应用程序根据某些设置进行不同的操作时,我就会遇到问题。例如,我有一个名为"短语"的模板,里面有一个变量"短语"。我想根据用户的设置更改它们的排序方式。
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)
我不知道是什么原因造成的
然而,这段代码确实有效!它确实会根据用户设置的内容对短语进行排序。但在控制台中,我可以看到每次更改设置时都会抛出此异常。第一次加载很好。
那么,我在这里是不是做错了什么?我必须承认,我还没有完全理解流星在幕后所做的事情。
我不知道这是否有帮助。但在尝试实现设置集合之前,我使用了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密码)具有用户特定设置的概念,内置为用户对象的"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});
};
你可能想使用一个类似iron路由器的软件包,它有钩子,可以确保你在加载数据之前真正拥有订阅。请参阅Iron Router。
- 将jQuery.ech()方法转换为本地JavaScript抽象的最佳方法是什么
- 处理浮点错误的最佳方法是什么
- javascript导入的最佳实践是什么
- 在ng重复循环中显示条件内容的最佳方式是什么
- 实现比较方法的最佳实践是什么;s的比较类型是在运行时选择的
- 以编程方式填充组合框道场 (1.8) 的最佳方法是什么?
- 在node.js中编写单元测试的最佳方式是什么
- 使用AJAX在Rails中提交动态表单的最佳方式是什么
- 使用Angular存储用户以前是否选中过复选框,然后再调用它的最佳方式是什么
- 列出没有 mysql 的元素的最佳方法是什么
- 在AngularJS中使用多个主题的最佳方式是什么
- 存储数据的最佳方式是什么,以便与jquery一起使用
- 在企业应用程序框架中包含js/css文件的最佳实践是什么
- 在d3.json中使用d3.csv组合多个csv文件数据输入的最佳方法是什么
- 用JavaScript随机给网页上的每个字母上色的最佳方式是什么
- 如果我返回表,检查 Ajax 调用是否为 200 OK的最佳方法是什么
- JavaScript - 创建可链接函数时的最佳方法是什么
- 在上下文菜单项单击上显示侧边栏/弹出窗口的最佳方法是什么
- 将JavaScript检测与MVC4显示模式集成的最佳方式是什么
- addEvent()传奇事件之后的当前最佳实践是什么