Knockout检查绑定不使用arrayObservable

时间:2017-09-29 10:15:09

标签: html knockout.js bootstrap-4

我有一个observableArray绑定到一对复选框。在选择/取消选中复选框时,数组应该会更改,因为它写在文档中:

  

如果您的参数解析为数组,则会给予特别考虑。在这种情况下,如果值与数组中的项匹配,KO将设置要检查的元素,如果数组中没有包含,则取消选中。

     

当用户选中或取消选中该复选框时,KO将添加或删除   相应的数组值。

但阵列没有改变。

以下是数组的淘汰代码:

self.filterByUserType = ko.observableArray(["Teacher","Student"]);

这里是html绑定:

<div id="LLClaimsButtons" class="btn-group" data-toggle="buttons">
    <div class="btn">
        <input data-bind="checked: filterByUserType" type="checkbox" value="Teacher" title="Profesor/a"><span class="fa fa-mortar-board"></span>
    </div>
    <div class="btn">
        <input data-bind="checked: filterByUserType" type="checkbox" value="Student" title="Alumno/a"><span class="fa fa-user"></span>
   </div>
</div>

这里有一点测试:

<div data-bind="foreach: filterByUserType">
    <div data-bind="text: $data"></div>
</div>

嗯,无论我对复选框做什么都没关系,因为数组总是一样的。

2 个答案:

答案 0 :(得分:1)

对于引导程序按钮内的复选框似乎没什么意义 - 您也可以将按钮上的单击绑定到视图模型中的功能,该功能可以执行添加/删除项目的工作

function ViewModel(){
	var self = this;
  self.filterByUserType = ko.observableArray(["Teacher","Student"]);
  self.click = function(data){          
      self.filterByUserType.indexOf(data) > -1 ? self.filterByUserType.remove(data) : self.filterByUserType.push(data) 
  
  }
}

ko.applyBindings(new ViewModel())
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="LLClaimsButtons" class="btn-group" data-toggle="buttons"> 
    <div class="btn" data-bind="click:function(){click('Teacher')}">
        <span class="fa fa-mortar-board"></span>
    </div>
    <div class="btn" data-bind="click:function(){click('Student')}">
        <span class="fa fa-user"></span>
   </div>
</div>

<hr>

 <div data-bind="foreach: filterByUserType">
   <div data-bind="text: $data"></div>
</div>

请注意,您可能需要以全屏模式查看该代码段 - 脚本错误不会影响执行但会妨碍执行。

答案 1 :(得分:0)

虽然@Jamiec的答案是完全正确的,但是如果 self.filterByUserType = ko.observableArray(["Teacher","Student"]); ko.bindingHandlers.checkboxButton = { init: function (element, valueAccessor) { var value = valueAccessor(); var $element = $(element); var $inputElement = $(element).find('input'); if ($inputElement) { $element.on('click', function () { var data = $inputElement.prop('value'); $element.hasClass("active") ? value.remove(data) : value.push(data); }); } }, update: function (element, valueAccessor) { var value = valueAccessor(); var $element = $(element); var $inputElement = $(element).find('input'); var data = $inputElement.prop('value'); value().indexOf(data) > -1 ? $element.addClass('active') : $element.removeClass('active'); } }; 数组被修改掉了'click'事件就会出现问题:那么按钮的状态(由点击时的Bootstrap控制)将是不同的数组的真实状态。

所以,部分基于Jamiec的解决方案(+1为此),我实现了一个对我来说很好的自定义绑定。这是:

    <div id="LLClaimsButtons">
        <div class="btn" data-bind="checkboxButton: filterByUserType">
            <input type="checkbox" value="Teacher" title="Profesor/a"><span class="fa fa-mortar-board"></span>
        </div>
        div class="btn" data-bind="checkboxButton: filterByUserType">
            <input type="checkbox" value="Student" title="Alumno/a"><span class="fa fa-user"></span>
        </div>
    </div>

现在,必须在复选框输入的父级中设置此绑定,将observableArray作为主要属性,使用与数组项目相同的字符串的“value”属性。

以下是我如何使用它:

data-toggle:buttons

正如你所看到的,我不再使用Bootstrap的{{1}}了,因为我在绑定中切换了'active'类。