バックグラウンド
私は、インターネットの経験がほとんどない人のために、いくつかのブログ ソフトウェアを設計している最中です。インターネットとのやり取りを観察すると、記入しなければならないフォームの数が増えるにつれて、クライアントはますますイライラします。これを改善するために、ブログの作成を 1 つのページにまとめ、すべての編集をインラインで行いたいと考えています。
彼らがブログ投稿を作成する方法は、
- コンテンツの「ブロック」を選択すると、キャンバスに配置されます。
- 素材に満足するまでインラインでブロックを編集し、
- 別のブロックを追加し、すすぎ、完了するまで繰り返します。
- 投稿を保存すると、データがセッションからサーバーに送信されます。
すべてのインライン コンテンツの作成を問題なく実行できるようにするパッケージを作成済みです。ただし、一般的に、ボールをプレーするためのスキーマを取得することは別の獣です。各ブロックを Spacebars テンプレートとして構成し、各投稿のテンプレート フィールドでレンダリングするテンプレートを指定したいと考えています。このアプローチがうまくいかないのは、可能性のあるすべての投稿に対して 1 つの大規模なスキーマが必要ないことです。大量の投稿を小さな投稿に削り取るのではなく、テンプレート フィールドに一致するように投稿のサブスキーマを拡張するとよいでしょう。残念ながら、Collection2 は、テンプレート フィールドに基づいてサブスキーマを動的に拡張できるようにするために、少し扱いにくいことがわかっています。
基本スキーマ
@Posts = new Mongo.Collection 'posts'
Schemas = {}
Blocks = {}
# B L O C K S -------------------------------------------------------------
Blocks.Title = new SimpleSchema
title:
type: String
defaultValue: 'Click me to enter a title for this post!'
max: 200
Blocks.Body = new SimpleSchema
body:
type: String
defaultValue: 'Click me to enter some body text!'
label: 'Body'
blockMap = {
'Title': Blocks.Title
'Body': Blocks.Body
}
# S C H E M A S -----------------------------------------------------------
#- START PROBLEM AREA ---
Schemas.Block = new SimpleSchema [
# Used by Spacebars to render dynamic templates.
template:
type: String
label: 'The name of the template into which this block is rendered.'
allowedValues: ->
return _.keys(Blocks) # Only allow blocks that exist to be set as templates.
data: # Uses the template field to elect which data it provides to it.
type: blockMap[@field('template').value]
]
#- END PROBLEM AREA ---
Schemas.Post = new SimpleSchema [ Schemas.Base,
blocks:
type: [Schemas.Block]
minCount: 2
]
@Posts.attachSchema(Schemas.Post)
備品データ:
Posts.insert
blocks: [
{
template: 'Title'
data:
title: 'Hello World!'
},
{
template: 'Body'
data:
body: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Labore dolorum, et nemo eius libero incidunt saepe est alias,
harum nesciunt ducimus facilis reiciendis. Sit odit,
laudantium. Provident laudantium, enim adipisci.'
}
]
実験
上で強調したセクションでは、上に書かれているように、data: { type: ... }
オブジェクトにはフィールド メソッドがありません。autoValue メソッドだけがそれにアクセスできるようですが、これは奇妙です。これもうまくいきません。
data:
type: eval('Blocks.' + @field('template').value)
# >> TypeError: Object #<Object> has no method 'field'
では、フィールドにアクセスするにはどうすればよいでしょうか。
type プロパティはコンストラクター関数に渡すことができるため、プロパティを適切に評価します。テンプレート プロパティからデータを受信できないようです。
ここからどこへ
残念ながら、これは私が探している動的なスキーマの構築を可能にしません。だから私の質問はこれです。コンストラクターをデータ フィールドの type プロパティに渡すことができる場合、テンプレート フィールドの値を何らかの形で渡して、テンプレートを動的にレンダリングできるようにする方法はありますか? Collection2はすごく便利なので使い続けたいです。私がいじっているもう 1 つのアプローチは、1 つの巨大なブロック スキーマを作成し、ブロック タイプごとに Collection2 でその一部を選択することです。
何かアドバイス?(リファクタリング、コードの受け渡しなど)