Подтвердить что ты не робот

Динамическая загрузка шаблонов в Meteor.js

Мне нужна возможность динамически загружать шаблоны без явного указания шаблона.

В качестве примера:

<template name="foo">
</template>

где 'foo' - это шаблон, я бы хотел, чтобы он динамически загружал его, вызывая некоторый метод:

Meteor.render(Meteor.loadTemplate('foo'));

Возможно ли это?

4b9b3361

Ответ 1

Meteor 0.9.x Новый API

Дэн Даскалеску отметил, что у Meteor теперь есть встроенные динамические шаблоны! Это хорошо, потому что вам не нужно включать дополнительный код, как показано в предыдущих версиях.

{{> Template.dynamic template=template [data=data] }}

Для Meteor 0.8.x Legacy

Динамический шаблон без данных: Boris Kotov обновленный Blaze (0.8.0) ответ на правильном пути (взято из последних документов), но он не работает как есть для меня. Я получил следующее:

{{> dynamicTemplate name=myDynName}}

<template name="dynamicTemplate">
    {{#with chooseTemplate name}}
        {{> template}}
   {{/with}}
</template>

Template.dynamicTemplate.chooseTemplate = function (name) {
    return { template: Template[name] };
};

Надеюсь, что есть более простое решение, но мне нужно было обернуть шаблон в JSON, как показано. Возможно, это поможет кому-то еще двигаться вперед.

Динамический шаблон с данными: если у вас есть и хотите, чтобы данные были динамическими, обязательно создайте вспомогательный метод, который может реагировать. Обязательно выполните Session.set() где-нибудь, чтобы увидеть эффект.

// Inside "myContainingTemplate"
{{> dynamicTemplateWithData name=myDynName data=myDataHelper}}

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

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

Template.myContainingTemplate.helpers({
    myDataHelper: function () {
        Session.get('myReactiveKey');
    }
});

Ответ 2

Здесь, как динамически отображать шаблоны, с Meteor 0.9.4 - 1.0. Все остальные ответы были устаревшими на момент написания этой статьи.

Скажем, вы редактируете кучу записей или создаете новую и хотите отобразить либо шаблон update, либо шаблон new на основе некоторых переменных сеанса.

Есть два способа сделать это:

1) Это официально рекомендованный метод для Meteor 0.9.4 или новее - он использует Template.dynamic:

<template name="records">
  {{> Template.dynamic template=whichOne}}
</template>

<template name="recordUpdate">
  ...
</template>

<template name="recordNew">
  ...
</template>

Template.records.helpers({
  whichOne: function () {
    return Session.get('edit') ? 'recordUpdate' : 'recordNew'
    // note that we return a string - per http://docs.meteor.com/#template_dynamic
  }
});

2) Это работает в разных версиях Meteor, но официально не рекомендуется, поскольку неясно, что шаблон выбран динамически:

<template name="records">
  {{> whichOne}}
</template>

{{! Note how "whichOne" is indistinguishable from a constant template name... }}
{{  ...like "recordUpdate" or "recordNew" below. }}

<template name="recordUpdate">
  ...
</template>

<template name="recordNew">
  ...
</template>

Template.records.helpers({
  whichOne: function () {
    return Session.get('edit') ? Template.recordUpdate : Template.recordNew
    // note that we return a Template object, not a string
  }
});

Чтобы передать контекст данных в шаблон, используйте:

{{> Template.dynamic template=whichOne data=myData}}

Ответ 3

Вы нашли Meteor.render, но то, что вам не хватает, это загрузка шаблона. В документах упоминается, что вы можете вызвать Template.foo(), чтобы вернуть HTML для шаблона.

http://docs.meteor.com/#template_call

Объединяя это, вы получаете доступ к шаблону foo или любому другому, используя доступ к скобкам так:

var templateName = "foo";
var fragment = Meteor.render( function() {
    return Template[ templateName ](); // this calls the template and returns the HTML.
});

Затем фрагмент - это ваш реактивный фрагмент, чтобы ваш шаблон мог продолжать получать текущие обновления. Теперь вашему фрагменту нужно разместить на веб-странице (я использую jQuery, поэтому этот пример тоже):

$("#htmlnode").html( fragment );

$( "# htmlnode" ) - это всего лишь node в вашей DOM, где вы хотите, чтобы созданный шаблон. И теперь у вас есть отображаемый контент на вашей веб-странице.

Ответ 4

Я просто делаю это так, не требуется jQuery:

EDITED

Template.mainContent.showContentFromRouter = function() {
    return Template[Meteor.Router.page()]();
};

В этом случае я использую Meteor Router и возвращаю любой шаблон, который я выбираю (из Router), но вы могли бы просто сделать это:

Template.mainContent.showDynamicContent = function() {
    return Template['someTemplateYouveDefined']();
};

Ответ 5

Обновление для пламени:

https://github.com/meteor/meteor/wiki/Using-Blaze#templatefoo-is-not-a-function-and-does-not-return-a-string

Динамически визуализировать шаблон с заданным контекстом данных

Старый:

{{dynamicTemplate name="templateName" data=dataContext}}

Template.foo.dynamicTemplate = function (opts) {
  return Template[opts.name](opts.data);
};

Новое: (Примечательно, что в Blaze аргументы ключевого слова для включения или блочные помощники объединяются в один объект, который становится новым контекстом данных)

{{> dynamicTemplate name="templateName" data=dataContext}}

<template name="dynamicTemplate">
  {{#with chooseTemplate name}}
    {{#with ../data}}  {{! original 'data' argument to DynamicTemplate}}
      {{> ..}}         {{! return value from chooseTemplate(name) }}
    {{/with}}
  {{/with}}
</template>

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

Кстати, я на самом деле не играл с этим, но это то, что я взял из новых документов blaze. Поэтому я думаю, что это должен быть способ сделать это;)

Ответ 6

Meteor 0.8.x Legacy

Используя ответ Joc в качестве руководства, Я добился аналогичного использования http://docs.meteor.com/#template_call, но вместо этого использовал помощник, как это было предложено документами:

При вызове внутри вспомогательного элемента шаблона, тела Meteor.render или других параметров, где генерируется реактивный HTML, полученный HTML-код аннотируется так, что он отображает как реактивные элементы DOM

Мой client.js выглядит примерно так:

Template.myPageTemplate.helpers({
  dynamicTemplate: function() {
    // conditional logic can be added here to determine which template to render
    return Template.myDynamicTemplate();
  }
});

и мой html выглядит так:

<template name="myPageTemplate">
  <h1>My Template</h1>
  {{{dynamicTemplate}}}
</template>

<template name="myDynamicTemplate">
  <h1>My Dynamic Template</h1>
</template>

Ответ 7

Из https://github.com/meteor/meteor/wiki/Using-Blaze

{{> post}}

Template.foo.helpers({
  post: function () {
    return Template[this.postName];
  }
});

Вложения шаблонов теперь ищут пространство имен помощников и данные для объектов шаблона, поэтому легко программно выбирать, какой шаблон использовать. Это мощная функция и позволит шаблонам, например, назначать один шаблон в качестве помощника другого, чтобы его можно было переопределить.

Ответ 8

Основанный на ответе на холм, это самый простой способ:

Template.main.template = function() {
  if (some_condition) {
    return Template.A();
  } else {
    return Template.B();
  }
};

С соответствующим .html

<body>
    {{> main}}
</body>

<template name="main">
    {{{template}}}
</template>

<template name="A">
    <h1>Template A</h1>
</template>

<template name="B">
    <h1>Template B</h1>
</template>

Edit Не работает в Meteor 0.8.0

Ответ 9

для меня самым простым способом было просто создать функцию get_dynamic_template, поэтому что-то вроде:

var a= get_dynamic_template(template_name,data);

который возвращает то, что может отображаться как нормальная переменная {{a}}

Код для этой функции довольно прост:

var get_dynamic_template = function(template_name,data)
{

      return function(){
        return new Handlebars.SafeString(
          UI.toHTML(
               Template[template_name].extend({data: function () { return data; }}))
          );
      };

}

Ответ 10

Это позволит обрабатывать динамические шаблоны как с данными, так и без них: (требуется Blaze/Meteor 0.8)

{{> dynamicTemplate name=templateName}}

<template name="dynamicTemplate">
    {{#with chooseTemplate name }}
        {{#if ../data}}
            {{#with ../data }}
                {{> .. }}
            {{/with}}
        {{else}}
            {{> this}}
        {{/if}}
    {{/with}}
<template name="dynamicTemplate">

шаблон javascript:

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