2

私はMeteorを初めて使用しますが、自分に思われることをどのように解決するかが一般的な問題です。

レストランを一覧表示するハンドルバーテンプレートがあるとします。

<template name="Restaurants">
  {{#each Restaurant}}
    {{name}}
  {{/each}}
</template>

ここで、ユーザーがレストランテンプレートをクリックすると、そのレストランのメニューを表示したいと思います。

特定のレストランのすべてのメニュー項目を含む「menuItems」という名前のサブテンプレートを追加しました。

<template name="Restaurants">
  {{#each Restaurant}}
    {{name}} 
    {{> menuItems}}
  {{/each}}
</template>

ユーザーがレストランテンプレートの任意の場所をクリックしたときに、menuItemsサブテンプレートのインスタンスを1つだけレンダリングしたい(選択したレストランのメニューアイテムのみをレンダリングする)。

次のようになります。

Template.Restaurants.events({
'click' : function (e) {
       // This is where I need help - what's the right way to display only one subtemplate instance?
     }
});

私の質問は、正しいmenuItemsテンプレートインスタンスのみを選択して表示するにはどうすればよいですか?

また、menuItemsテンプレートインスタンスをDOMに配置したいのは、クリック後のみで、前ではありません(すべてのレストランのすべてのメニュー項目を保持し、それらのdivのみを非表示にすることは、db内の項目の数が多いため、オプションではありません)。

他の方法で解決策に取り組む必要があると思われる場合は、お知らせください。ありがとうございます。

4

2 に答える 2

4

とを使用する必要が{{#if}}ありSessionます。このような:

<template name="Restaurants">
  {{#each Restaurant}}
    {{name}} 
    {{#if restaurantSelected}}
      {{> menuItems}}
    {{/if}}
  {{/each}}
</template>

リアクティブデータソースであるを使用することによりSession、レストランが選択されているかどうかを示すグローバルフラグを設定できます。

Template.Restaurants.restaurantSelected = function() {
  // check whether this restaurant is selected. "this" refers to the current
  // context, eg. the current restaurant in the loop
  return Session.equals("restaurantSelected", this._id);
}

そのセッションキーを変更するたびに、値が更新され、テンプレートが再描画されます。したがって、レストランをクリックするときに切り替えることができます。

Template.Restaurants.events({
  'click' : function (e) {
    // store the current restaurant ID
    // make sure the event selector is correct!
    Session.set("restaurantSelected", this._id);
  }
});

編集わかりやすくするために、プロジェクトにコピーして試すことができる完全な例を作成しました。

于 2012-12-26T00:23:59.183 に答える
1

私はほとんどの場合、セッションを避けます。それはグローバルスコープを汚染すると思います。また、テンプレートの複数のインスタンスを実行することもできなくなります。テンプレートインスタンスにスコープされたreactiveVarまたはreactiveDictを使用することをお勧めします。デモプロジェクトを開始してくれたRahulに感謝します。私は彼の例を取り上げ、それを修正して私の推奨するアプローチを示しました。

テンプレートインスタンスonCreateにreactiveDictをアタッチします。グローバルSessionvarの代わりにこれを使用して状態を保存します!

Template.Restaurants.onCreated(function() {
  this.state = new ReactiveDict;
  this.state.set('currentRestaurant', null); // could set a init value here
});

このイベントハンドラーは、クリック時にreactiveDictの状態を設定します

'click': function(e, t) {
    t.state.set('currentRestaurant', this._id);
}

このヘルパーは、メニューテンプレートを表示/非表示にするために使用されます

currentRestaurant: function() {
// check whether this restaurant is selected. "this" refers to the current
// context, eg. the current restaurant in the loop
return Template.instance().state.equals("currentRestaurant", this._id);
},

メニューテンプレートは、セッションからではなく、データコンテキストから選択されたIDを受け取ります

<template name="Restaurants">
  <ul>
    {{#each Restaurant}}
    <li>
      {{name}}
      {{#if currentRestaurant}}
      {{> menuItems restaurant=_id}}
      {{/if}}
      </li>
    {{/each}}
  </ul>
</template>

<template name="menuItems">
  <ul>
    <li class="menu">I'm a menu for {{restaurantName}}!</li>
  </ul>
</template>

本当にIDを取得したことを示すためにこのヘルパーを追加しました

Template.menuItems.helpers({
  restaurantName: function() {
    var restaurantMenu = Restaurants.findOne(this.restaurant);
    return restaurantMenu.name;
  },
})

完全に機能するプロジェクトをgithubに投稿しました。 https://github.com/white-rabbit-japan/scopedReactivityDemo

アプリはmeteor.comhttp://scopedreactitivydemo.meteor.com/でホストされてい ます

于 2015-04-16T07:16:54.107 に答える