Допустим, у нас есть данные следующего вида
var data = {
facets: [{
name : "some name",
values: [{
value: "some value"
}]
}]
};
Мы можем легко представить это в виде модели представления, привязанной к шаблону knockout следующим образом:
<ul data-bind="foreach: facets">
<li>
<span data-bind="text: name"></span>
<ul data-bind="foreach: values">
<li data-bind="text: value"></li>
</ul>
</li>
</ul>
Вопрос в том, как мы можем достичь того же результата при использовании прогрессивного улучшения? То есть путем первоначального рендеринга шаблона на стороне сервера, а затем привязки шаблона knockout и модели представления к этому рендерингу.
Простой шаблон на стороне сервера будет выглядеть примерно так:
<ul>
<li>
<span>some name</span>
<ul>
<li>some value</li>
</ul>
</li>
</ul>
Я исследовал несколько различных возможностей:
Одна из них заключается в создании одного шаблона knockout и одного шаблона на стороне сервера, а модель представления Knockout генерируется динамически путем разбора DOM для шаблона на стороне сервера. Таким образом, только шаблон Knockout будет виден, если включен JavaScript, и только шаблон на стороне сервера будет виден, если JavaScript отключен. Их можно стилизовать таким образом, чтобы они выглядели идентично.
Другой подход заключается в применении привязок для каждого элемента в массиве фасетов отдельно к существующему элементу DOM для этого фасета. Однако это все еще только один уровень глубины и не работает для вложенных элементов.
Ни один из этих подходов не кажется достаточно чистым. Другим решением может быть написание пользовательской привязки, которая обрабатывает весь рендеринг и повторно использует существующие элементы, если это возможно.
Есть другие идеи?