私の流星プロジェクトでは、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>
それを meteor と統合する最善の方法が何かわからないので、アドバイスを求めています。
私はいくつかのアプローチを試しました:
(1) 入力要素を含むテンプレートの .created に初期化コードを入れます。
<template name="hello">
<input type="text" value="Amsterdam,Washington" data-role="tagsinput" />
</template>
template.hello.created = function () {
$('input').tagsinput({...});
}
これは当然のようです。ただし、テンプレートが再レンダリングされると、初期化データが失われ、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"
例外スタックは役に立たなかった (ほとんどが「spark」コード) ため、このパスを放棄することになりました (ただし、機能させることができれば、これが最善の方法であると思います)。
(3) .rendered 関数でタグ入力を初期化する:
template.hello.rendered = function () {
$('input').tagsinput({...});
}
プラグインは初期化を一度だけ受け入れるため、これも失敗します。2 番目の初期化は機能しません。tagsinput() 引数が関数プロパティ名であると想定し、それを実行しようとします (またはこれらの行に沿ったもの)。
(4)(3)をさらに進めて、初期化されたデータを削除することで裏をかくと思いました:
template.hello.rendered = function () {
$('input').removeData('tagsinput');
$('input').tagsinput({...});
}
これにより、input 要素の 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({...});
}
このコードで仕事は完了しますが、非常にハックであり、meteor または tagsinput が更新されると壊れる可能性があります。
流星忍者の誰かがタグ入力を初期化する正しい方法を教えてくれたら、それは素晴らしいことです!