Knockout使用foreach渲染复选框

时间:2015-11-15 14:08:59

标签: javascript jquery knockout.js

这是我对knockout的第一次体验。我找不到如何使用foreach呈现复选框列表。

我尝试了什么:

<div class="col-sm-12" data-bind="foreach: placeCategories">
    <label class="col-sm-6" data-bind="text: name">
         <input type="checkbox" data-bind="value: val">
    </label>
</div>

但我只得到名字,没有复选框。可能标签内部html被覆盖。但是如何同时显示复选框和文本?

2 个答案:

答案 0 :(得分:1)

来自documentation

  

text绑定使用您的参数值将内容设置为文本节点。之前的任何内容都将被覆盖。

因此,您需要对text

上的其他元素使用span绑定
<div class="col-sm-12" data-bind="foreach: placeCategories">
    <label class="col-sm-6"> 
         <span data-bind="text: name"></span>
         <input type="checkbox" data-bind="value: val">
    </label>
</div>

或者您也可以使用无容器语法:

<div class="col-sm-12" data-bind="foreach: placeCategories">
    <label class="col-sm-6"> 
         <!--ko text: name--><!--/ko-->
         <input type="checkbox" data-bind="value: val">
    </label>
</div>

答案 1 :(得分:0)

是的,你需要使用ko注释标签或多个子元素(例如spans),以避免绑定相互覆盖。

只是为了好玩,你 CAN 覆盖Knockout text绑定以允许这种行为。下面的代码将测试data-bind属性的元素内容,如果找到任何内容,请在元素的开头插入text-node,同时保留其他绑定。

&#13;
&#13;
var app = {
  placeCategories: [
    {name: ko.observable('A'), val: ko.observable(false)},
    {name: ko.observable('B'), val: ko.observable(false)},
    {name: ko.observable('C'), val: ko.observable(false)}
  ]
};

ko.bindingHandlers.text.update = function(element, valueAccessor) {
   var hasBindings = element.innerHTML.match('data-bind'),
       value = ko.utils.unwrapObservable(valueAccessor());
  
   if (hasBindings) {
     if (element.firstChild.nodeType !== 3)
       element.insertBefore(document.createTextNode(' '), element.firstChild);
     element.firstChild.nodeValue = value;
   } else
     element.nodeValue = value;
};

ko.applyBindings(app);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class="col-sm-12" data-bind="foreach: placeCategories">
    <label class="col-sm-6" data-bind="text: name">
         <input type="checkbox" data-bind="value: val">
    </label>
</div>
&#13;
&#13;
&#13;

注意:我不鼓励这样做,但这是可能的。我宁愿创建一个新的自定义绑定来允许它。