Last time I posted a code snippet with description of data driven Knockout views. I have modified and simplified it and
- added support for
forEach
binding and - the
type
member ofViewModel
class can return a function that is evaluated for every item in collection
This brings even more flexibility, the view model itself can decide which view to use based on a value returned from type
function.
define([ 'knockout' ], function(ko) { ko.bindingHandlers.content = { 'init': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var options = ko.utils.unwrapObservable(valueAccessor()); var templateNameFunc = function(value, itemBindingContext) { if('template' in options) return options['template']; if(!value['type']) { throw new Error("Set 'type' of view model class."); } var type = value.type; if(typeof type == 'function') type = type(); return type.replace(/viewmodel/ig, 'View'); }; if ('foreach' in options) { var dataArray = (options['foreach']) || []; ko.renderTemplateForEach(templateNameFunc, dataArray, options, element, bindingContext); return; } var templateName = templateNameFunc(options.data), dataValue = ko.utils.unwrapObservable(options['data']); var innerBindingContext = bindingContext['createChildContext'](dataValue, options['as']); ko.renderTemplate(templateName || element, innerBindingContext, options, element); } }; });
The example will follow soon.