нокаут с динамическими моделями представления

#ajax #viewmodel #knockout.js

#ajax #viewmodel #knockout.js

Вопрос:

В интернете есть много информации о том, как обрабатывать динамические представления (с помощью вызовов ajax) с помощью Knockout, но есть ли лучшая практика для динамических моделей представления?

Например, скажем, у меня есть одностраничное приложение, которое отображает (через ajax) различные типы форм (с разными полями ввода) на основе роли, выбора пользователя, контекстов и т.д. Я бы не только использовал шаблоны для каждой формы, но и хотел бы сделать то же самое для viewmodel, поскольку каждая viewmodel может иметь много очень разных свойств, и было бы непрактично иметь одну массивную viewmodel для каждого возможного шаблона.

Я немного новичок в ko, и, возможно, он не предназначен для использования таким образом. Любой совет очень ценится.

Ответ №1:

Популярный способ сделать это — иметь модель основного представления, в которой размещаются модели вложенных представлений.

Вот действительно простой пример определения объектов «модели», которые имеют шаблон и связанные с ним данные.

 function Model(key, template, data) {
   this.key = key;
   this.template = ko.observable(template);
   this.data = data; 
}

var viewModel = {
   models: ko.observableArray([
       new Model("user", "userTmpl", { first: "Bob", last: "Smith" }),
       new Model("item", "itemTmpl", { name: "MyItem", description: "Here are some details" })
   ]),
   selectedModel: ko.observable()
};

ko.applyBindings(viewModel);
  

Затем вы могли бы использовать его как:

 <select data-bind="options: models, optionsText: 'key', optionsCaption: 'select a model...', value: selectedModel"></select>

<hr />

<div data-bind="with: selectedModel">
    <div data-bind="template: { name: template(), data: data }"></div>    
</div>


<script id="userTmpl" type="text/html">
    <span data-bind="text: last"></span>, <span data-bind="text: first"></span>
</script>

<script id="itemTmpl" type="text/html">
    <h3 data-bind="text: name"></h3>
    <div data-bind="text: description"></div>
</script>
  

http://jsfiddle.net/rniemeyer/29kWf/

Очевидно, что вы вряд ли свяжете выбор модели в select, но это помогает показать, как это может работать. Вместо массива ваши модели могут быть объектом с именами свойств, соответствующими ключу.

«Данные» в объектах «модели» будут вашими моделями подвидов.

Комментарии:

1. Спасибо, Райан, я думаю, что начинаю видеть KO более четко. Было бы правильно использовать эту методологию с добавлением плагина сопоставления KO для привязки данных (имя, фамилия, имя, описание и т. Д.) В качестве наблюдаемых? В моем сценарии я извлекаю данные через ajax. На самом деле, если я в конечном итоге извлекаю как шаблоны, так и данные через ajax, я должен иметь возможность просто вызвать «applyBindings» в успешном обратном вызове, чтобы подключить все — правильно? Я попробую это в выходные, когда у меня будет немного свободного времени.

2. Определенно хорошо использовать плагин сопоставления с этой идеей. Вызов applyBindings успешного обратного вызова — это нормально. Вы действительно хотите вызвать его только один раз, если только вы не передаете второй параметр, чтобы ограничить его определенным элементом, и выполняете только несколько вызовов для элементов, которые не являются потомками. В противном случае, в примере, который я предоставил, вы можете вызвать applyBindings заранее, и пока selectedModel не будет заполнен, на самом деле ничего не будет привязано.

Ответ №2:

Я сталкиваюсь с той же проблемой.

Попробуйте нокаут пространства имен