8

では、データベースにを保存<div>{{name}}</div>しているとしましょう。<div>{{age}}</div>次に、最初の HTML 文字列を取得してテンプレートにレンダリングします。これは、ハンドルバーを{{> template1}}含む最初の文字列をレンダリングするだけです。{{name}}次に、新しく生成されたテンプレート/html データを提供して、ハンドルバーにnameデータベースからの実際のデータを入力できるようにして、 <div>John</div>. やってみました

<template name="firstTemplate">
    {{#with dataGetter}}
        {{> template1}}
    {{/with}}
</template>

template1 が次のように定義されている場所

<template name="template1">
    {{{templateInfo}}}
</template>

そして templateInfo は、ハンドルバーを含む前述の html 文字列をデータベースから返すヘルパーです。

dataGetter はまさにこれです(単なる例です。私は別の名前のコレクションを扱っています)

Template.firstTemplate.dataGetter = function() {
    return Users.findOne({_id: Session.get("userID")});
}

{{name}} を取得できません。いくつかの方法で試してみましたが、文字列内のハンドルバーをデータで評価する必要があることを Meteor が理解していないようです。私は 0.7.0 を使用しているため、Blaze はありません。使用している他のパッケージが原因で、現時点ではアップグレードできません。まだ 0.8 以降のバージョンをサポートしていません。これを機能させる方法についてのアイデアは大歓迎です。

4

6 に答える 6

9

1.0 では、上記の方法はどれも機能しません。クライアントコードで定義された以下の関数でこれを機能させました。重要なのは、オプション { isTemplate: true} をコンパイル関数に渡すことでした。

var compileTemplate = function(name, html_text) {
  try {
    var compiled = SpacebarsCompiler.compile(html_text, { isTemplate:true });
      var renderer = eval(compiled);
      console.log('redered:',renderer);
      //Template[name] = new Template(name,renderer);
      UI.Template.__define__(name, renderer);
  } catch (err){
    console.log('Error compiling template:' + html_text);
    console.log(err.message);
  }
};

クライアントで次のような方法で呼び出すことができます。

compileTemplate('faceplate', '<span>Hello!!!!!!{{_id}}</span>');

これは、HTML で動的な UI を使用してレンダリングされます。

{{> Template.dynamic template='faceplate'}}

于 2014-11-14T05:43:15.650 に答える
8

スペースバー コンパイラを使用して、実際に文字列をテンプレートに自分でコンパイルできます。使用する必要があるのはmeteor add spacebars-compiler、それをプロジェクトに追加するだけです。

0.8.x を使用するプロジェクトで

var compiled = Spacebars.compile("<div>{{name}}</div> and <div>{{age}}</div>");
var rendered = eval(compiled);

Template["dynamicTemplate"] = UI.Component.extend({
  kind: "dynamicTemplate",
  render: rendered
});

0.9.x を使用するプロジェクトで

var compiled = SpacebarsCompiler.compile("<div>{{name}}</div> and <div>{{age}}</div>");
var renderer = eval(compiled);

Template["dynamicTemplate"] = Template.__create__("Template.dynamicTemplate", rendered);
于 2014-05-02T17:05:59.177 に答える
3

@ user3354036の回答に続いて:

var compileTemplate = function(name, html_text) {
  try {
    var compiled = SpacebarsCompiler.compile(html_text, { isTemplate:true }),
        renderer = eval(compiled);

    console.log('redered:',renderer);
    //Template[name] = new Template(name,renderer);
    UI.Template.__define__(name, renderer);
  } catch (err) {
    console.log('Error compiling template:' + html_text);
    console.log(err.message);
  }
};

1)これをHTMLに追加します

 {{> Template.dynamic template=template}}

2) compileTemplate メソッドを呼び出します。

compileTemplate('faceplate', '<span>Hello!!!!!!{{_id}}</span>');
Session.set('templateName','faceplate');

テンプレート名をセッション変数に保存します。この重要性については、次のポイントで説明します。

3) テンプレート名を返すヘルパー関数を記述します。そのためにセッション変数を使用しました。これは、クリック イベントで動的コンテンツを追加する場合、または親テンプレートが既にレンダリングされている場合に重要です。そうしないと、動的テンプレートがレンダリングされることはありません。

'template' : function() {
  return Session.get('templateName');
}

4) これが親テンプレートのレンダリングされたメソッドであると記述します。これは、セッション変数をリセットすることです。

Session.set('templateName','');

これは私にとってはうまくいきました。それが誰かを助けることを願っています。

于 2016-02-25T11:29:43.040 に答える
1

幸いなことに、この問題全体および同様の問題に対する解決策は、リアクティブなテンプレートを可能にするコア Meteor パッケージであるBlaze パッケージの形で Meteor API に提供されています。リンクされたドキュメントを見ると、Blaze パッケージには、リアクティブ コンテンツと非リアクティブ コンテンツの両方をプログラムで作成、レンダリング、および削除するための幅広いソリューションを可能にする関数の長いリストが用意されています。

上記の問題を解決するには、次のことを行う必要があります。

まず、アプリケーション用に動的にレンダリングする必要があるさまざまな HTML チャンクを予測します。この場合、これらのチャンクは<div>{{name}}</div>andになります<div>{{age}}</div>が、実際には有効な HTML であれば何でもかまいません (ただし、まだパブリック API の一部ではありませんが、将来、開発者はこのコンテンツをより動的な方法で定義するためのオプションが増える予定です。ドキュメントでここに記載されているように)。これらを次のように小さなテンプレート定義に入れます。

<template name="nameDiv">
    <div>{{name}}</div>
</template>

<template name="ageDiv">
    <div>{{age}}</div>
</template>

次に、firstTemplateテンプレートの定義を変更して、次のようにプログラムで参照できる HTML ノードを含める必要があります。

<template name="firstTemplate">
    <div></div>
</template>

firstTemplate次に、Blaze パッケージによって提供される関数の一部、つまりBlaze.WithBlaze.render、およびBlaze.removeを利用するテンプレート用にロジックを定義する必要があります (ただし、次のロジックを変更して、代わりにBlaze.renderWithData関数を使用します。これはすべて、ロジックをどのように定義するかについての個人的な好みに基づいています - 説明のために、以下に考えられる解決策を 1 つだけ示します)。

Template.firstTemplate.onRendered(function() {
    var dataContext = Template.currentData();
    var unrenderedView = Blaze.With(dataContext, function() {
        // Define some logic to determine if name/age template should be rendered
        // Return either Template.nameDiv or Template.ageDiv
    });
    var currentTemplate = Template.instance();
    var renderedView = Blaze.render(unrenderedView, currentTemplate.firstNode);

    currentTemplate.renderedView = renderedView;
});

Template.firstTemplate.onDestroyed(function() {
    var renderedView = Template.instance().renderedView;
    Blaze.remove(renderedView);
});

onRenderedしたがって、テンプレートの関数でここで行っていることはfirstTemplate、ページにレンダリングするデータ (名前または年齢のいずれか) を動的に決定し、Blaze.With()関数を使用してそのテンプレートのレンダリングされていないビューを作成することです。firstTemplateテンプレートのデータ コンテキストを使用します。次に、firstTemplate動的に生成されたコンテンツを含めるテンプレート要素ノードを選択し、両方のオブジェクトを関数に渡しますMeteor.render()。これにより、指定された要素ノードをレンダリングされたコンテンツの親ノードとしてページにレンダリングされていないビューがレンダリングされます。

関数の詳細を読むと、レンダリングされたビューが関数を使用して削除されるか、指定された親ノードが DOM から削除さBlaze.render()れるまで、このレンダリングされたコンテンツはリアクティブのままであることがわかります。Blaze.remove()上記の例では、呼び出しから受け取ったレンダリングされたビューへの参照を取得し、Blaze.render()それをテンプレート オブジェクトに直接保存しています。これは、テンプレート自体が破棄されたときに、レンダリングされたビューをonDestroyed()コールバック関数で手動で削除し、確実に破棄されるようにするためです。

于 2015-08-18T01:56:21.267 に答える
1

複雑なテンプレートを動的にコンパイルする 必要がある場合は、Kelly の回答をお勧めします。

それ以外の場合は、次の 2 つのオプションがあります。

  1. すべてのテンプレート バリエーションを作成してから、適切なテンプレートを動的に選択します。

    たとえば、テンプレートを作成します

    <template name="displayName">{{name}}</template>
    <template name="displayAge">{{age}}</template>
    

    そして、それらを動的に含めます

    {{> Template.dynamic template=templateName}}
    

    またはtemplateName返すヘルパーはどこですか"age""name"

  2. テンプレートが単純な場合は、自分で置換を実行してください。Spacebars.SafeStringHTML を返すために使用できます。

    function simpleTemplate(template, values){
          return template.replace(/{{\w+}}/g, function(sub) {
              var p = sub.substr(2,sub.length-4);
              if(values[p] != null) { return _.escape(values[p]); }
              else { return ""; }
          })
    }
    Template.template1.helpers({
      templateInfo: function(){
          // In this context this/self refers to the "user" data
          var templateText = getTemplateString();
          return Spacebars.SafeString(
              simpleTemplate(templateText, this)
          );
      }
    
于 2014-05-01T23:52:06.833 に答える
1

非常に簡単な方法は、グローバル Blaze オブジェクトへの呼び出しを onRendered イベントに含めることです。

Blaze.renderWithData(Template[template_name], data ,document.getElementById(template_id))
于 2016-01-26T21:07:30.967 に答える