- 1. Knockout.js 2. Knockout.js 外部テンプレート エンジン (ifandelse) [infuser、trafficcop を間接的に使用]、3、Sammy JS、Require JS などを使用してアプリケーションを開発しています。
モジュール性と開発の容易さを促進するために、ページごとに複数のビューモデルを使用するようにアプリケーションを設計しています。Ryan Niemeyer ( http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html ) からのバインドのヒントを使用して、applyBindings のオーバーロードされたバージョンを使用して複数のビューモデルをバインドする方法について説明します。この手法は、Jim Cowart の Knockout.js External Template Engine ライブラリを使用することを決定するまでは問題なく機能していました。これは、テンプレートをファイルに分割し、それらを非同期的にロードするのに役立ちます。機能しない理由は単純です。applyBinding がビューモデルを特定の DOM 要素にバインドするには、DOM 要素が存在する必要があります (テンプレートが要求され、KO 外部テンプレート エンジンによって非同期的に読み込まれるため、そうではありません)。afterRenderなども使えません。
誰かがこのシナリオに出くわしましたか? この点に関する提案、方向性は非常に役立ちます。使用できる KO の機能が不足していますか?
今のところ、回避策として、HTML でテンプレートを定義する際に「templateLoaded」コールバックを追加しました。
<!--ko template: {name: 'header', templateUrl: '/templates/shell', templateLoaded: function () { header.bindViewModel.call(header) }} -->
<!--/ko-->
HTML テンプレート:
<!-- ko stopBinding: true -->
<header id="divHeader">
<!-- Template Code using Header viewmodel -->
</header>
<!-- /ko -->
ヘッダー ビューモデル:
bindViewModel = function () {
ko.applyBindings(this, $("#divHeader").get(0));
}
Knockout.js メソッド「executeTemplate()」を次のように変更しました。
if (haveAddedNodesToParent) {
if (options.templateLoaded ) {
options.templateLoaded.call(bindingContext['$data']);
}
activateBindingsOnContinuousNodeArray(renderedNodesArray, bindingContext);
if (options['afterRender'])
ko.dependencyDetection.ignore(options['afterRender'], null, [renderedNodesArray, bindingContext['$data']]);
}
現在、テンプレートが非同期的に取得され、解析され、DOM にロードされた後に、コールバックが呼び出されます。これは、ビューモデルを正しい要素にバインドするのに役立ちます。