Запрашиваемая вами функция в основном не поддерживается Blaze.В то время как генераторы статического кода могут легко включать динамические теги, это очень сложный способ во время выполнения, когда вам приходится иметь дело с деревом DOM, чьи типы тегов элементов являются неизменяемыми по конструкции.
Сначала я подумал об обходном пути, который использует дочернюю перестановку с использованием jQuery в onRendered
из MyTag
:
Template.MyTag.onRendered(function () {
const instance = this
instance.autorun(() => {
const data = Template.currentData()
const attributes = data.attributes || {}
const elementName = data.tag
const refTag = instance.$('.my-tag-ref')
const newTag = $(`<${elementName}>${refTag.html()}</${elementName}>`)
Object.keys(attributes).forEach(attKey => newTag.attr(attKey, attributes[ attKey ]))
newTag.addClass('my-tag-ref')
refTag.replaceWith(newTag)
})
})
Но, к сожалению, , к сожалению, не работает , поскольку блок содержимого теряет свою реактивность и экземпляр jQueryтекущего шаблона теряет область видимости для корневого элемента.Я просто добавляю его сюда на тот случай, если кто-то поймает это и найдет решение, которое работает.
Теперь есть решение, работающее с использованием динамических шаблонов:
<Template name="MyTag">
{{#Template.dynamic template=getTemplate data=getData}}
{{> Template.contentBlock }}
{{/Template.dynamic}}
</Template>
<template name="mytaga">
<a {{attributes}}>
{{> Template.contentBlock }}
</a>
</template>
<template name="mytagform">
<form {{attributes}}>
{{> Template.contentBlock }}
</form>
</template>
<template name="mytagdiv">
<div {{attributes}}>
{{> Template.contentBlock }}
</div>
</template>
Как вы можете видетьнедостатком является то, что вам нужно определить множество новых шаблонов.Преимущество состоит в том, что вам больше не нужно использовать так много if / else, и оно выплачивается, тем чаще вам придется включать в свой код MyTag
.
Соответствующие помощники выглядят следующим образом:
Template.MyTag.helpers({
getTemplate() {
const instance = Template.instance()
console.log(instance.data)
return `mytag${instance.data.tag}`
},
getData () {
return Template.instance().data
}
})
Это работает, но мне интересно, много ли это для Метеора (и обновлений DOM).Это решение работает как простой {{#if}} ... {{/ if}} или оно намного тяжелее?
Blaze в целом медленнее, чем, например, React или Vue.Однако рендеринг обновляется только в том случае, если обновляются реактивные данные, поэтому он так же велик, как и количество запускаемых обновлений.