删除克隆元素上的knockout js绑定 [英] Remove knockout js bindings on cloned element

查看:76
本文介绍了删除克隆元素上的knockout js绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用knockout js模板绑定功能将一组项目呈现给元素:

I am using the knockout js template binding functionality to render a collection of items to an element:

<script type="text/javascript">
    ko.applyBindings(new function () {
        this.childItems = [{ Text: "Test", ImageUrl: "Images/Image.png" }];
    });
</script>

<script type="text/html" id="template">
    <div class="childItem" data-bind="attr: { title: Text }">
        <img data-bind="attr: { src: ImageUrl }" />
    </div>
</script> 

<div class="childSelector" data-bind="template: { name: 'template', foreach: childItems }">
</div>

点击后,子项目将被克隆并放入另一个元素中:

When clicked, the child items are cloned and placed into another element:

$(".childSelector").on("click", ".childItem", function () {
    var clone = $(this).clone()[0];
    ko.cleanNode(clone);
    $(".targetNode").append(clone);
});

问题是当源数据发生变化并且模板重新绑定到新数据时,抛出以下错误:

The problem is that when the source data changes and the template is re-bound to the new data, the following error is thrown:


未捕获错误:无法解析绑定。消息:ReferenceError:
未定义文本;绑定值:attr:{title:Text}

Uncaught Error: Unable to parse bindings. Message: ReferenceError: Text is not defined; Bindings value: attr: { title: Text }

我找到了另一篇建议使用 ko.cleanNode的帖子(元素)删除knockout的绑定,但是在我的情况下这还没有解决问题。

I had found another post that suggested using ko.cleanNode(element) to remove knockout's bindings, however this has not resolved the issue in my case.

有没有办法删除敲除的绑定一个克隆元素,以防止重新绑定时出现此错误?如果不是,我只是通过从点击的元素中提取所需数据来手动克隆元素。

Is there a way to remove knockout's bindings on a cloned element to prevent this error when re-binding? If not I'll just "manually" clone the element by extracting the required data from the clicked element.

这里是我正在做的一个简单示例

Here is a simple example of what I'm doing

推荐答案

你可以通过遍历DOM并删除 data-bind 属性和淘汰注释来删除元素中的所有knockout绑定。

You can remove all knockout bindings from an element by traversing the DOM and removing the data-bind attributes and knockout comments.

使用 removeDataBindings(clone); 但首先使用 ko.cleanNode(clone)清除节点以清除任何事件处理程序。

Use removeDataBindings(clone); but first clean the node with ko.cleanNode(clone) to clear any event handlers.

var commentNodesHaveTextProperty = document.createComment("test").text === "<!--test-->";
var startCommentRegex = commentNodesHaveTextProperty ? /^<!--\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*-->$/ : /^\s*ko(?:\s+(.+\s*\:[\s\S]*))?\s*$/;
var endCommentRegex =   commentNodesHaveTextProperty ? /^<!--\s*\/ko\s*-->$/ : /^\s*\/ko\s*$/;

function isStartComment(node) {
    return (node.nodeType == 8) && (commentNodesHaveTextProperty ? node.text : node.nodeValue).match(startCommentRegex);
}

function isEndComment(node) {
    return (node.nodeType == 8) && (commentNodesHaveTextProperty ? node.text : node.nodeValue).match(endCommentRegex);
}

function traverseNode(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        traverseNode(node, func);
        node = node.nextSibling;
    }
}

function removeDataBindings(element) {
    var koComments = [];

    traverseNode(element, function (node) {
        if (isStartComment(node) || isEndComment(node)) {
            koComments.push(node);
            return;
        }
        //remove the 'data-bind' attributes
        if (node.nodeType === 1) { //ELEMENT_NODE
            node.removeAttribute('data-bind');
        }
    });

    //remove Knockout binding comments
    for (i = 0; i < koComments.length; i++) {
        node = koComments[i];
        if (node.parentNode) {
            node.parentNode.removeChild(node);
        }
    }
}

这篇关于删除克隆元素上的knockout js绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆