在我的流星项目中,我使用的是 bootstrap-tagsinput 插件:
http://timschlechter.github.io/bootstrap-tagsinput/examples/
我在'typeahead'模式下使用它,因此它需要初始化,如下所示:
<input type="text" value="Amsterdam,Washington" data-role="tagsinput" />
<script>
$('input').tagsinput({
typeahead: {
source: function(query) {
return $.getJSON('citynames.json');
}
}
});
</script>
我无法弄清楚将它与流星集成的最佳方法是什么——所以我正在寻求建议。
我尝试了几种方法:
(1) 将初始化代码放在包含输入元素的模板的.created中:
<template name="hello">
<input type="text" value="Amsterdam,Washington" data-role="tagsinput" />
</template>
template.hello.created = function () {
$('input').tagsinput({...});
}
这似乎很自然。但是,当模板重新渲染时,初始化数据会丢失,输入元素不会像标签输入一样。
(2) 与 (1) 相同,但添加 {{#constant}} 指令。{{#constant}} 指令防止根据流星文档重新渲染。如果插件只初始化一次并且从不重新渲染,则该插件应该可以工作:
(顺便说一句,添加 div 是有原因的,请参阅:)
{{#constant}}
<div>
<input type="text" value="Amsterdam,Washington" data-role="tagsinput" />
</div>
{{/constant}}
这失败了:
"Exception from Deps recompute: Error:
An attempt was made to reference a Node in a context where it does not exist"
异常堆栈是无用的(主要是“火花”代码),所以我最终放弃了这条路(但我怀疑这仍然是最好的方法,只要我能让它工作)。
(3)在.rendered函数中初始化tagsinput:
template.hello.rendered = function () {
$('input').tagsinput({...});
}
这也失败了,因为插件只接受一次初始化。第二次初始化将不起作用:它期望 tagsinput() arg 是一个函数属性名称并尝试执行它(或类似的东西)。
(4) 我想我会采取 (3) 进一步并通过删除初始化数据来超越它:
template.hello.rendered = function () {
$('input').removeData('tagsinput');
$('input').tagsinput({...});
}
这将清除输入元素处的 data['tagsinput'] 并允许重复的 tagsinput 初始化。一旦 data['tagsinput'] 不存在,初始化就会进行并重新创建它。这个技巧几乎解决了它,除了一个小的副作用:一个自动生成的 div 元素在 DOM 中徘徊。tagsinput 插件的工作方式是在 input 元素之后添加一个兄弟 div:
<input data-role="tagsinput" ... />
<div class="bootstrap-tagsinput">...</div> <-- auto-generated by tagsinput
一旦解决方案尝试 (4) 运行,偶尔的 div 将与新生成的 div 一起保留在 dom 中。此时我开始觉得这个解决方案不符合流星精神,但我决定尝试使用以下方法摆脱挥之不去的 div:
template.hello.rendered = function () {
$('input').removeData('tagsinput');
$(".bootstrap-tagsinput").remove();
$('input').tagsinput({...});
}
这段代码完成了工作,但它非常hackish,并且在更新流星或标签输入时可能会中断。
如果你们中的任何一个流星忍者都能说出初始化标签输入的正确方法,那就太棒了!