[英]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.