編集:以下のコードは壊れやすいため、テストしやすいようにコンテキストに入れるために更新しました。注意事項も追加しました。ほとんどの場合、@zorlak または @englandpost のメソッドを使用することをお勧めします (以下を参照)。
まず、誰も答えなかった私の古い質問を掘り下げてくれた @zorlak に敬意を表します。@David Wihl から収集したいくつかの洞察でこれを解決し、独自のソリューションを投稿します。他の人が検討する機会があるまで、正しい答えを選択するのを保留します.
@zorlak の回答は、単一フィールドのオートコンプリートの問題を解決しますが、質問に記載されているように、リアクティブに更新される配列を探していました。オートコンプリートは、その使用目的の一例にすぎません。この配列を持つ利点は、(テンプレート ヘルパーだけでなく) どこでも使用できることと、クエリを再実行する必要なくコード内で複数回使用できることです (そして、_.pluck()
クエリを配列に減らします)。 . 私の場合、この配列は複数のオートコンプリート フィールドと、検証やその他の場所で終了します。私が提示している利点は、ほとんどの Meteor アプリでは重要ではない可能性があります (コメントを残してください) が、これは私にとって利点のように思えます。
配列をリアクティブにするには、単純にMeteor.autorun()
コールバック内に構築します。これは、ターゲット コレクションが変更されるたびに再実行されます (ただし、その場合に限り、繰り返しのクエリを回避します)。これが私が求めていた重要な洞察でした。また、コールバックを使用することは、私が質問で使用したテンプレート ヘルパーTemplate.rendered()
よりもクリーンでハックが少なくなります。set_typeahead
以下のコードは、underscore.js_.pluck()
を使用してコレクションから配列を抽出し、Twitter ブートストラップ$.typeahead()
を使用してオートコンプリートを作成します。
更新されたコードmeteor create
: ストックd テスト環境でこれを試すことができるように、コードを編集しました。HTML には<input id="typeahead" />
、'hello' テンプレートの行が必要です。コンソールでグローバルとして使用できるようにするため@Items
の@
記号があります ( Meteor 0.6.0 でファイルレベルの変数スコープが追加されました)。そうすれば、コンソールに などの新しい項目を入力できますが、コードが機能するためには必要ありません。スタンドアロンでの使用に必要なその他の変更は、typeahead 関数がソースを関数 ( ) に設定するようになったことです。これにより、レンダリング時に設定されるのではなく、アクティブ化されたときにクエリが実行され、 への変更を利用できるようになります。Items
Items.insert({name: "joe"})
@
->
items
items
@Items = new Meteor.Collection("items")
items = {}
if Meteor.isClient
Meteor.startup ->
Meteor.autorun ->
items = _(Items.find().fetch()).pluck "name"
console.log items #first result will be empty - see caution below
Template.hello.rendered = ->
$('#typeahead').typeahead {source: -> _(Items.find().fetch()).pluck "name"}
注意!作成した配列自体は、リアクティブ データ ソースではありません。返される関数に typeaheadsource:
を設定する必要がある理由は、Meteor が最初に起動したときに、Minimongo がサーバーからデータを取得する前にコードが実行され、空の配列に設定されるためです。Minimongo はそのデータを受け取り、更新されます。コンソールを開いた状態で上記のコードを実行すると、このプロセスを確認できます。データが保存されている場合は、2 回ログに記録されます。 ->
items
items
items
console.log items
Template.x.rendered()
呼び出しは反応性コンテキストを設定しないため、反応性要素の変更により再トリガーされません (これを確認するには、デバッガーでコードを一時停止して調べDeps.currentComputation
ますnull
。反応要素への影響は無視されます)。items
しかし、テンプレートとヘルパーも変更に反応しないことを知って驚くかもしれません。#each
繰り返し処理をitems
行うために使用するテンプレートは空でレンダリングされ、再レンダリングされません。リアクティブ ソースとして機能させることができます (最も簡単な方法は、結果を で保存するSession.set()
か、自分で行うことができます)。)、しかし、可能な限り実行する必要のない非常に高価な計算を行っている場合を除き、@zorlak または @englandpost の方法を使用する方が適切です。アプリがデータベースに繰り返しクエリを実行するのはコストがかかるように思えるかもしれませんが、Minimongo はネットワークを回避してデータをローカルにキャッシュしているため、非常に高速です。したがって、ほとんどの状況では、単に使用する方が良いです
Template.hello.rendered = ->
$('#typeahead').typeahead {source: -> _(Items.find().fetch()).pluck "name"}
アプリが本当に動かなくなっていることが判明しない限り。