Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockoutjs programmatic databinding to generated interface

Tags:

knockout.js

I'm working on a rapid prototyping tool for which I would like to dynamically generate the interface, and dynamically databind data to the created elements. The ViewModel would look something like:

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

The vmSchema would be used to create the interface elements based on their type, and then vmData would databind to those elements.

Creating the interface is no problem. The challenge is programatically databinding the vmData mdoel to the generated interface.

Are there any tools or techniques that would allow this type of programmatic databinding?

like image 363
dcpar Avatar asked Nov 16 '12 23:11

dcpar


1 Answers

It looks like your model's fields and types won't be known until runtime. For this kind of dynamically generated model, you'd need to write some code that turns its properties into observables, assuming that you need two-way binding. At the most basic, you could iterate through vmData and turn everything in it into a ko.observable:

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

As to the view binding, it depends on what's "creating the interface elements". If they can add data-bind attributes to the HTML elements at creation time, then everything should be straightforward: just run ko.applyBindings as soon as the interface is created and attached to the DOM. If for some reason you cannot add the data-bind decorations, then you can manually specify bindings using the slightly undocumented ko.applyBindingsToNode.

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

The above is equivalent to <span class="some_elm" data-bind="value: vmData.id"></span>.

like image 154
zetlen Avatar answered Oct 07 '22 23:10

zetlen