5

アプリ設定とユーザー固有の設定を実装する方法を示す 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'

特定の設定に基づいてアプリの動作を変えようとすると、私が抱えている問題が発生します。たとえば、'phrases' という変数を内部に持つ 'phrases' というテンプレートがあります。ユーザーの設定に基づいて並べ替え方法を変更したい。

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});
};

これは問題なく機能しました。それは本当の柔軟性ではありません。

これを行うべき別の方法はありますか?誰かがたまたま知っているなら、流星を作っている人たちがそこで個人的なテスト/プロジェクトの設定のために何をしているのか知りたい.

長い投稿で申し訳ありませんが、私はすでに試したことなどについてどのような質問がされるかを予想しようとしていました.

ご協力いただきありがとうございます。

4

3 に答える 3

11

Meteor アカウント システム (例: accounts-password) には、ユーザー オブジェクトの「プロファイル」フィールドとして組み込まれているユーザー固有の設定の概念があります。これは自動的に公開され、リアクティブでもあります (Meteor.user() はリアクティブであるため)。

関連するドキュメントは次のとおりです。http://docs.meteor.com/#meteor_user

「nodeName」エラーに関しては、デバッグが困難ですが、通常、そのエラーが発生するのは、実際には存在しないテンプレート ヘルパーの DOM の一部にアクセスしようとしているからです。また、誤って同じ ID を持つ 2 つの DOM 要素を持っていたときにも見ました (サブテンプレートを使用すると、かなり簡単に実行できます)。

それを追跡するために、問題が発生しなくなるまでコードを削除し、根本的な原因が見つかるまで少しずつ追加し直します。

于 2013-10-04T16:34:11.667 に答える
1

Meteor 用に作成したユーザー セッション スマート パッケージは、このユース ケースに最適です。

基本的に Meteor の に似Sessionていますが、各変数はユーザーに関連付けられています。リアクティブで、すべての変更が永続的です。これは、クライアント、および追加のuserId引数を使用してサーバーで使用できます。

于 2013-09-02T19:06:36.510 に答える
0

ここでのエラーは、サーバー側の 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-router のようなパッケージを使用したいと思うでしょう。Iron Routerを参照してください。

于 2013-11-20T08:56:30.793 に答える