通过Knockout组合文本和HTML

时间:2012-08-24 12:53:11

标签: javascript html knockout.js

这就是我想要构建我的html

的方法
<a href="#">John <i class="person"></i></a>

使用knockout.js这就是我所做的。

<a data-bind="text:name"><i class="person"></i></a>

正如您可以猜测锚的整个元素(不仅仅是文本)被删除,因为在这种情况下,文本绑定中的整个标记被删除。我的解决方案如下。

<a data-bind="html: name() + '<i class="person"></i>'"></a>

在data-bind中使用html进行字符串连接是一种解决方案,但它有两大缺点。 'name'propery不安全所以我们可以得到html注入。在数据绑定属性中写入html是很糟糕的。

另一种解决方案是。

<a href="#"><span data-bind="text:name"></span><i class="person"></i></a>

我知道我们为解决方案引入了新的html标记。这是我发现最好的。

knockout.js中这个问题的众所周知的解决方案是什么?

我们可以指定只更新文本而不是通过参数更新文本中的整个元素吗?

还是更好的解决方案?

2 个答案:

答案 0 :(得分:9)

使用span是首选解决方案。如果文本绑定没有替换所有内容,那么它很难知道要更新的内容,并且下次更改时不会更新。如果你想总是处理元素的第一个子节点,那么你可以写一个小的自定义绑定来帮助。

这是一个简单的prependText绑定。这将始终替换包含绑定的元素的第一个子节点。因此,您需要确保第一个节点至少是一个空格。

ko.bindingHandlers.prependText = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        //replace the first child
        element.replaceChild(document.createTextNode(value), element.firstChild);
    }        
};

使用它像:

<a href="#" data-bind="prependText: name"> <span> another element</span></a>

示例:http://jsfiddle.net/rniemeyer/5CfzH/

答案 1 :(得分:6)

您还可以使用KO“无容器”符号

<!-- ko text: YourProperty -->
<!-- /ko-->

其他绑定(例如foreach)也可以这样做:See Part 4