web-dev-qa-db-ja.com

Meteorのテンプレートに変数を渡す方法はありますか?

私はMeteorを試していて、わからないことがありました。楽しみのために、私はスロットマシンを作ろうとしていました。次のHTMLがありました。

<div class="slot-wrapper">
  {{> slot}}
  {{> slot}}
  {{> slot}}
</div>

<template name="slot">
  <div class="slot">
    <div class="number"><span>{{ number }}</span></div>
    <div class="divider"></div>
  </div>
</template>

スロットごとに異なる番号が必要です。変数をテンプレートに渡すことは可能ですか?このようなもの:

<div class="slot-wrapper">
  {{> slot 1}}
  {{> slot 2}}
  {{> slot 3}}
</div>

<template name="slot">
  <div class="slot">
    <div class="number"><span>{{ number i}}</span></div>
    <div class="divider"></div>
  </div>
</template>

たぶん私はこれについて間違った方法を考えていて、もっと良い方法があります。

62
Jordan Brown

これまでの回答はすべて、やり過ぎまたは時代遅れです。 Meteor 0.8.xの時点で、HTML + Spacebarsコードから直接、静的パラメーターをテンプレートに渡す方法は次のとおりです。

<div class="slot-wrapper">
  {{> slot number="1"}}
  {{> slot number="2"}}
  ...
</div>

<template name="slot">
  <div class="number"><span>{{number}}</span></div>
</template>

key="value"インクルージョンコールで{{> template}}パラメーターを渡すだけです:

{{> slot number="1"}}

Spacebars Secrets:Exploring Meteor Templates で詳細をご覧ください。


呼び出し元テンプレートのデータを子/ネストされた/呼び出されたテンプレートに渡したい場合、次のようにします:何も渡しません。代わりに、ネストされたテンプレートから、親データコンテキスト../にアクセスします。

<div class="slot-wrapper">
  {{> slot number="1"}}
  {{> slot number="2"}}
  ...
</div>

<template name="slot">
  <div>Machine name: {{../name}}</div>
  <div class="number"><span>{{number}}</span></div>
</template>
90
Dan Dascalescu

別の方法があることがわかりました。

私はさまざまな検索をグーグルで調べることでこれを行う方法を見つけようとしていましたが、この質問を見つけましたが、私の目的に合ったものはありませんでした。親テンプレートの別の場所にネストされたテンプレートを配置する場合を除き、TomUniteの答えは機能します。

そのため、多くの検索を行った後、流星のコードベースで「ある」答えを見つけました。 (それが決定的な答えだとは言わないが、うまくいく)

<template name="slots">
  {{> slot one}}
  <div>..something else</div>
  {{> slot three}}
  {{> slot two}}
</template>

<template name="slot">
  <div class="slot">
    <div class="number"><span>{{number}}</span></div>
    <div class="divider"></div>
  </div>
</template>

ご覧のとおり、テンプレートインスタンスは任意の順序で指定できます。 2番目のパラメーターは、実際には定義する必要がある変数なので、次のとおりです。

Template.slots.one = {
  number: 1
}
Template.slots.two = {
  number: 2
}
Template.slots.three = {
  number: 3
}

これは、ループを使用してより簡潔なコードにするか、slotsオブジェクトでunderscore.js関数_.extendを使用することができます。また、データの複数のフィールドをこれらのオブジェクトに渡すことができます。

14
Joc

これはコメントとして残したかったのは、Jocの答えを明確にするためだけでしたが、できなかったので、ここに加えて私が取り組んだ例があります。

テンプレートに渡すことができる引数は1つだけです。

{{> singleItemInfo arg1}}

この引数は、次のようなオブジェクトでなければなりません。

{
    number: 1,
    number2: 2,
    numberComposite: {
        subnum1: 10,
        subnum2: 20
    }
};

引数値はキーを介してアクセスでき、スコープを切り替えてサブアイテムを取得できます

{{#with numberComposite}}

例の完全なコードは次のとおりです。

<htmlファイル>

<body>
    {{ itemsView }}
</body>

<template name="itemsView">
    {{> singleItemInfo arg1}}
</template>

<template name="singleItemInfo">
    arg1 = {{ number }}
    arg2 = {{ number2 }} 
    {{#with numberComposite}}
        subArg1 = {{ subnum1 }}
        subArg2 = {{ subnum2 }}
    {{/with}}
</template>

<javascriptファイル>

Template.itemsView.arg1 = {
    number: 1,
    number2: 2,
    numberComposite: {
        subnum1: 10,
        subnum2: 20
    }
};

出力:

arg1 = 1 arg2 = 2 subArg1 = 10 subArg2 = 20 
9
jay

より良い回答:

新しいBlazeレイアウトでテンプレートをコンテキスト依存にするために使用できる2つのソリューションは次のとおりです。

1)引数をテンプレートに直接渡す

{{> contextSensitiveTemplate  context_1='x' context_2='y' }}

2)コンテキストを理解するテンプレートでヘルパーを使用します。次のようにヘルパーを呼び出します。

{{ contextHelperName ../.. .. this }}

そして

Template.contextSensitiveTemplate.contextHelperName = function(parent_template, current_template, current_value_inside_each_loop) {
  return context_dependent_value_or_html     
}
5
Jim

これは私がそれを達成するために行ったことです。私はMeteorにかなり慣れていないので、もっと良い方法があるかもしれません:

Slot.html:

<head>
  <title>Slot</title>
</head>

<body>
  <div class="slot-wrapper">
    {{> slots}}
  </div>
</body>

<template name="slots">
  {{#each slots}}
    {{> slot}}
  {{/each}}
</template>

<template name="slot">
  <div class="slot">
    <div class="number"><span>{{number}}</span></div>
    <div class="divider"></div>
  </div>
</template>

Slot.js:

if (Meteor.is_client) {
  Template.slots.slots = function () {
    var returnArray = new Array();
    returnArray[0] = { 'number': 10 };
    returnArray[1] = { 'number': 87 };
    returnArray[2] = { 'number': 41 };
    return returnArray;
  };
}

if (Meteor.is_server) {
  Meteor.startup(function () {
    // code to run on server at startup
  });
}

これがあなたの助けになることを願っています!

3
Thomas Lomas

通常、これら2つのHandlebarsヘルパーを使用します。

Handlebars.registerHelper('partial', function(templateName, options) {
    return new Handlebars.SafeString(Template[templateName](options.hash));
});

Handlebars.registerHelper('partialWithContext', function(templateName, context, options) {
    var extendedContext = _.extend(context, options.hash);
    return new Handlebars.SafeString(Template[templateName](context));
});

次のように使用できます(menuItemというテンプレートがあるとします):

{{partial 'menuItem' command='Open'}}

または、反復内で(userProfileというテンプレートがあると仮定します):

{{#each regularUsers}}
    {{partialWithContext 'userProfile' . isAdmin=false}}
{{/each}}

{{#each admins}}
    {{partialWithContext 'userProfile' . isAdmin=true}}
{{/each}}

スペースバーを使用すると、多少似た動作を実現できます。 partial.js

Template.partialWithContext.chooseTemplate = function (name) {
    return Template[name];
};

partial.html

<template name="partialWithContext">
    {{#with chooseTemplate name}}
        {{#with ../data}}
            {{> ..}}
        {{/with}}
    {{/with}}
</template> 

次のように使用します。

{{#each commands}}
    {{> partialWithContext name="commandListItem" data=this isAdmin=false}}
{{/each}}
{{#each adminCommands}}
    {{> partialWithContext name="adminCommandListItem" data=this isAdmin=true}}
{{/each}}

それがトリックをすることを願っています。

2
Zsolt

引数を1つだけ渡す場合は、thisを使用します。

<div class="slot-wrapper">
    {{> slot 1}}
    {{> slot 2}}
</div>

<template name="slot">
    <div class="slot">
        <div class="number"><span>{{this}}</span></div>
        <div class="divider"></div>
    </div>
</template>

JavaScriptを実行する必要はありません。引数以上のものが必要な場合は、ダンの方法を試してください。

2
Isaac Han

この情報は古く、引数の受け渡しについては、Blazeレイアウトエンジンの詳細をここで説明します: https://www.discovermeteor.com/blog/spacebars-secrets-exploring-meteor-new-templating-engine/

0
Jim

ここにたくさんの良い情報があります。私の特定の状況は、いくつかのテンプレートデータを渡すこともしたいです。

子Blazeコンポーネントを再利用できるようにしたいので、すべてのデータを渡す必要があります。例として、このコンポーネントがグレード(A、B、Cなど)を示しているとしましょう。ページ上で、コンポーネントを2回使用します:成績とクラスメートの平均成績。

これが子コンポーネントです...

Grade.html

<template name="Grade">
    <h3>{{title}}</h3>
    <div>{{grade}}</h3>
</template>

タイトルは親でハードコーディングできますが、グレードはデータベースから取得されます。ここで私は親をコーディングする方法です...

GradePage.html

<template name="GradePage">
    {{> Grade grade=gradeYours title="Your Grade" }}
    {{> Grade grade=gradeClass title="Class Grade" }}
</template>

GradePage.js(実際には反応的ですが、ここでは単純化されています)

Template.GradePage.helpers({
    gradeYours: function () {
        return 'A-';
    },
    gradeClass: function () {
        return 'B+';
    }
});

それでおしまい。子コンポーネントは、値を取得するためにまったく手を差し伸べる必要はありません。

0
zim