Программная привязка данных Knockoutjs к созданному интерфейсу

Я работаю над инструментом быстрого прототипирования, для которого я хотел бы динамически генерировать интерфейс и динамически привязывать данные к созданным элементам. ViewModel будет выглядеть примерно так:

var viewModel = {
    vmSchema: { 
            "Id" : "int",
            "Name" : "string",
            "UpdatedOn" : "date"
    },
    vmData: { 
            "Id": "123"
            "Name" : "Bob",
            "UpdatedOn" : "2012-11-16T00:00:00"
    }
}

vmSchema будет использоваться для создания элементов интерфейса на основе их типа, а затем vmData будет привязывать данные к этим элементам.

Создание интерфейса не представляет проблемы. Задача состоит в том, чтобы программировать привязку vmData mdoel к созданному интерфейсу.

Существуют ли какие-либо инструменты или методы, которые позволили бы использовать этот тип программных привязок данных?

Ответы

Ответ 1

Похоже, что ваши модели и типы моделей не будут известны до выполнения. Для такого рода динамически сгенерированной модели вам нужно написать код, который превращает его свойства в наблюдаемые, предполагая, что вам требуется двусторонняя привязка. В самом основном, вы можете перебирать vmData и превращать все в него в ko.observable:

for (var member in viewModel.vmData) {
   if (viewModel.vmData.hasOwnProperty(member)) {
       viewModel.vmData[member] = ko.observable(viewModel.vmData[member]);
   }
}

Что касается привязки вида, это зависит от того, что "создает элементы интерфейса". Если они могут добавлять атрибуты data-bind к элементам HTML во время создания, то все должно быть простым: просто запустите ko.applyBindings, как только будет создан интерфейс и подключен к DOM. Если по какой-то причине вы не можете добавить украшения data-bind, тогда вы можете вручную указать привязки, используя слегка недокументированные ko.applyBindingsToNode.

// manually specify a binding for an element
var elm = document.getElementById('some_elm');
ko.applyBindingsToNode(elm, { value: viewModel.vmData.id}, viewModel.vmData );

Вышеупомянутое эквивалентно <span class="some_elm" data-bind="value: vmData.id"></span>.