Use knockoutjs virtual element to create html part

2019-06-20 14:47发布

I am trying to use "virtual element" with html binding to create html part on the fly but failed with message: "The binding 'html' cannot be used with virtual elements". Here is the jsfiddle: http://jsfiddle.net/d3Dpp/.

Anyone knows if there is any workaround?

3条回答
爷、活的狠高调
2楼-- · 2019-06-20 15:24

You could also use this as your view:

<div data-bind="html: html"></div>​​​​​​​​​​​​​​​​​​​​​

This will replace the innerHtml of the div "container" with your provided html property.

查看更多
戒情不戒烟
3楼-- · 2019-06-20 15:31

Based on Artem's code and KnockoutJS 2.2.1, here's an improved version:

http://jsfiddle.net/YZzDe/2/

Improvements:

  1. Less code, less duplication (hooks in to exposed interfaces)
  2. Overrides 'html' binding, so basically the old 'html' can now be used in virtuals
  3. No more global functions.

Here's the code

{
    var overridden = ko.bindingHandlers['html'].update;

    ko.bindingHandlers['html'].update = function (element, valueAccessor) {
        if (element.nodeType === 8) {
            var html = ko.utils.unwrapObservable(valueAccessor());

            ko.virtualElements.emptyNode(element);
            if ((html !== null) && (html !== undefined)) {
                if (typeof html !== 'string') {
                    html = html.toString();
                }

                var parsedNodes = ko.utils.parseHtmlFragment(html);
                if (parsedNodes) {
                   var endCommentNode = element.nextSibling;
                   for (var i = 0, j = parsedNodes.length; i < j; i++)
                      endCommentNode.parentNode.insertBefore(parsedNodes[i], endCommentNode);
                }
            }
        } else { // plain node
            overridden(element, valueAccessor);
        }
    };
}
ko.virtualElements.allowedBindings['html'] = true;
查看更多
做个烂人
4楼-- · 2019-06-20 15:44

Well, after some playing with knockout I see that it is possible.

Working example is here

http://jsfiddle.net/d3Dpp/42/

unfortunatelly this requires duplication of some internal knockout functionality

UPDATE

KnockoutJS 2.2.1 added virtual elements binding to export, so it is available even in minified version:

ko.exportSymbol('virtualElements.allowedBindings', ko.virtualElements.allowedBindings);

It means that better solution for html binding is possible - see Martijn's answer.

查看更多
登录 后发表回答