7

这就是我想要构建我的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>

在数据绑定中使用 html 的字符串连接是一种解决方案,但它有两个很大的缺点。'name' 属性不安全,因此我们可以进行 html 注入。偶尔在数据绑定属性中编写 html 很糟糕。

另一种解决方案是。

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

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

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

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

还是更好的解决方案?

4

2 回答 2

10

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

这是一个简单的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/

于 2012-08-24T13:14:00.373 回答
6

您还可以使用 KO“无容器”表示法

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

其他绑定(例如 foreach)也可以这样做:参见第 4 部分

于 2014-01-14T20:35:01.363 回答