我自己做了一个工作示例:http: //jsfiddle.net/m34wp/4/
var templateComputedDomDataKey = '__ko__templateComputedDomDataKey__';
function disposeOldComputedAndStoreNewOne(element, newComputed) {
var oldComputed = ko.utils.domData.get(element, templateComputedDomDataKey);
if(oldComputed && (typeof (oldComputed.dispose) == 'function')) {
oldComputed.dispose();
}
ko.utils.domData.set(element, templateComputedDomDataKey, (newComputed && newComputed.isActive()) ? newComputed : undefined);
}
function makeArray(arrayLikeObject) {
var result = [];
for(var i = 0, j = arrayLikeObject.length; i < j; i++) {
result.push(arrayLikeObject[i]);
}
;
return result;
}
function moveCleanedNodesToContainerElement(nodes) {
var nodesArray = makeArray(nodes);
var container = document.createElement('div');
for(var i = 0, j = nodesArray.length; i < j; i++) {
container.appendChild(ko.cleanNode(nodesArray[i]));
}
return container;
}
ko.bindingHandlers['nested'] = {
'init': function (element, valueAccessor) {
var elementType = 1;
var commentType = 8;
var bindingValue = ko.utils.unwrapObservable(valueAccessor());
if(element.nodeType == elementType || element.nodeType == commentType) {
// It's an anonymous template - store the element contents, then clear the element
var templateNodes = element.nodeType == 1 ? element.childNodes : ko.virtualElements.childNodes(element);
var container = moveCleanedNodesToContainerElement(templateNodes);
new ko.templateSources.anonymousTemplate(element)['nodes'](container);
}
return {
'controlsDescendantBindings': true
};
},
'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var options = ko.utils.unwrapObservable(valueAccessor());
var outerTemplateName = options['to'];
var dataValue = ko.utils.unwrapObservable(options['data']) || viewModel;
var innerContext = bindingContext['createChildContext'](dataValue);
innerContext.innerTemplateElement = element;
var templateComputed = ko.renderTemplate(outerTemplateName, innerContext, options, element);
disposeOldComputedAndStoreNewOne(element, templateComputed);
}
};
ko.bindingHandlers['here'] = {
'init': function (element, valueAccessor) {
return {
'controlsDescendantBindings': true
};
},
'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var templateElement = bindingContext.innerTemplateElement;
if(viewModel != null) {
var innerContext = bindingContext['createChildContext'](viewModel);
var templateComputed = ko.renderTemplate(templateElement, innerContext, {
}, element);
disposeOldComputedAndStoreNewOne(element, templateComputed);
} else {
}
}
};
ko.virtualElements.allowedBindings['nested'] = true;