К счастью, решение всей этой проблемы и любых других подобных проблем было предоставлено Meteor API в виде Пакет Blaze, который является основным пакетом Meteor, делающим возможными реактивные шаблоны. Если вы посмотрите на связанную документацию, пакет Blaze предоставляет длинный список функций, которые позволяют использовать широкий спектр решений для программного создания, рендеринга и удаления как реактивного, так и нереактивного контента.
Для того, чтобы решить описанную выше проблему, вам необходимо сделать следующее:
Во-первых, предусмотрите различные фрагменты HTML, которые должны быть динамически отображены для приложения. В этом случае эти фрагменты будут <div>{{name}}</div>
и <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.With, Blaze.render и Blaze.remove (хотя вы можете изменить следующую логику и воспользоваться преимуществами Blaze.renderWithData; все зависит от ваших личных предпочтений относительно того, как вы хотите определить свою логику - я предоставьте только одно возможное решение ниже для объяснения).
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()
, которая отображает неотображенное представление на странице с указанным узлом элемента в качестве родительского узла отображаемого содержимого. .
Если вы прочтете подробности о функции Blaze.render()
, вы увидите, что это отображаемое содержимое будет оставаться реактивным до тех пор, пока отображаемое представление не будет удалено с помощью функции Blaze.remove()
или указанный родительский узел не будет удален из DOM. В моем примере выше я беру ссылку на визуализированное представление, которое я получил от вызова Blaze.render()
, и сохраняю его непосредственно в объекте шаблона. Я делаю это для того, чтобы при уничтожении самого шаблона я мог вручную удалить отрендеренное представление в функции обратного вызова onDestroyed()
и быть уверенным, что оно действительно уничтожено.
person
Keith Dawson
schedule
18.08.2015