IE8 を使用している場合、JavaScript でツリー オブジェクトをレンダリングする際に問題があります。HTML ページに階層を記述するには、ノックアウト テンプレートを使用してツリー オブジェクトを再帰的にレンダリングする必要があります。
ノックアウト コンポーネントを使用して、requirejs と require.text を使用して最終結果をレンダリングしています。
コンポーネントは、IE8 を除くすべてのブラウザーで正常に動作しています。IE8 を使用すべきではないことはわかっていますが、これは企業のイントラネット サイトであり、現在すべてのブラウザーを簡単にアップグレードすることはできません。テンプレートを使用して単純なリストに数字のリストのみをレンダリングするようにコードを単純化しました。
test.vm.js の ViewModel は次のとおりです。
define(['knockout'], function(ko) {
function TestViewModel() {
var self = this;
self.Title = "Example";
self.List = [
{ Name: "1" },
{ Name: "2" },
{ Name: "3" },
{ Name: "4" }
];
}
return TestViewModel;
});
test.view.js のビューは次のとおりです。
<script type="text/html" id="testTemplate">
<li data-bind="text: Name"></li>
</script>
<div>
<div data-bind="text: Title"></div>
<ul data-bind="template: {name: 'testTemplate', foreach: List}">
</ul>
</div>
最後に、コンポーネントを呼び出す HTML ページ:
<html>
<head>
<meta charset="utf-8" />
<title>App</title>
<script src="Scripts/jquery-1.10.2.js"></script>
<script src="Scripts/require.js"></script>
</head>
<body>
<script type="text/javascript">
require.config({
baseUrl: "/",
paths: {
'knockout': 'Scripts/knockout-3.2.0',
'text': 'Scripts/require.text'
}
});
$(document).ready(function () {
require(['knockout'], function (ko) {
ko.applyBindings();
});
});
require(['knockout'], function (ko) {
ko.components.register('TestComponent', {
viewModel: { require: 'Scripts/test.vm' },
template: { require: 'text!Scripts/test.view.js' }
});
});
</script>
<!-- ko component: { name: "TestComponent" } -->
<!-- /ko -->
</body>
</html>
DOM をブラウジングして確認できる主な違いは、テンプレートが他のブラウザーで完全にレンダリングされることです。
<script id="testTemplate" type="text/html">
<li data-bind="text: Name"></li>
</script>
IE8では空です
<SCRIPT id=testTemplate type=text/html __ko__1453323521948="ko12"></SCRIPT>
テンプレート「testTemplate」をビュー ファイルの外に配置し、HTML ページに直接配置すると、コンポーネントが動作し始めます。テンプレートが空であるため、コンポーネントが機能していません。HTMLに「testTemplate」を配置することは部分的な解決策ですが、ビューファイル内に配置すると機能しない理由を見つける必要があります。
更新: シナリオを単純化しました。どうやら、コンポーネント登録の「テンプレート」パラメーターに何らかのバグがあるようです。テンプレートが script タグで囲まれている場合、コンテンツは無視され、ページに表示されません。<template>
タグを使用するように変更すると、コンポーネントはテンプレート内のデータ バインディングを解決しようとし、エラーが表示されます。テンプレート タグはバインディングでは無視されるはずですが、コンポーネントはタグを無視しません。テンプレートを textarea タグで囲み、display:none を配置することで、最後に読んだタグをテンプレートで無視するように構成して、一時的なハックを試みました。コンテンツはすべてのブラウザーでレンダリングされるようになりましたが、このソリューションは気に入りません。