在knockout中点击复选框不会更新viewmodel

时间:2017-11-16 13:39:17

标签: javascript java knockout.js

我有复选框列表,点击任何复选框我需要获取所有选中的复选框。为此,我调用java脚本函数" ChangeColumnSelection"。

问题是,单击的复选框不会立即更新视图模型。当我单击下一个文本框时,我看到先前的复选框值已在视图模型中更新。

 <ul class="list-group" data-bind="foreach: SelectionColumnList">
      <li class="list-group-item">
          <input type="checkbox" data-bind="attr: {onclick: 'javascript:ChangeColumnSelection(\'' + ColumnID + '\')'}, checked: IsSelected"
                        class="pull-xs-left push-down rightmargin" />
          <span data-bind="text: ColumnName"></span>
     </li>
 </ul>

更新

我的观点模型是

  var dynamicGridViewModel = {
        SelectionColumnList: ko.observableArray([])
   }; 

    selectionInfo.ColumnID = columnInfo.ColumnID;
    selectionInfo.ColumnName = columnInfo.ColumnName;
    selectionInfo.DisplayOrder = columnInfo.DisplayOrder;
    selectionInfo.SortType = 'None';
    selectionInfo.IsSelected = true;
    dynamicGridViewModel.SelectionColumnList.push(selectionInfo);

1 个答案:

答案 0 :(得分:3)

您不需要onclick次活动。您只需使用checked binding

即可实现此目的

&#13;
&#13;
var array = [{
  ColumnID: 1,
  ColumnName: "ColumnName 1"
}, {
  ColumnID: 2,
  ColumnName: "ColumnName 2"
}]

var viewModel = function() {
  var self = this;
  self.SelectionColumnList = ko.observableArray(array);
  
  // no need to populate the array manually. Knockout will take care of it
  self.chosenItems = ko.observableArray();

  // every time chosenItems array changes, subscribe callback function gets triggered
  self.chosenItems.subscribe(function() {
    console.log(self.chosenItems());
  })
}

ko.applyBindings(new viewModel());
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<ul class="list-group" data-bind="foreach: SelectionColumnList">
  <li class="list-group-item">
    <input type="checkbox" data-bind="checkedValue: ColumnID, checked: $parent.chosenItems" />
    <span data-bind="text: ColumnName"></span>
  </li>
</ul>
&#13;
&#13;
&#13;

此处,ColumnId设置为checkbox输入的值。因此,chosenItems数组将是一个选定ColumnId的数组。

关于Knockout的好处是,它不仅允许primitive typescheckedValue那样使用字符串,数字或布尔值,而且还允许使用对象。如果您希望在Column中填充整个chosenItems对象,则可以像这样设置checkedValue

<input type="checkbox" data-bind="checkedValue: $data, checked: $parent.chosenItems" />

如果要在更改任何复选框的状态时执行某些操作,可以在subscribe回调中执行该操作。每次数组更改时都会触发此函数。

(另外,添加click binding的正确方法是data-bind="click: clickFunction"

<强>更新

您正在使用对象文字作为您的viewModel。我建议你创建viewModel函数并使用new运算符。如果要将checked绑定到布尔属性Column,则可以为该计算属性创建computed属性和subscribe

&#13;
&#13;
var columns = [{
  ColumnID: 1,
  ColumnName: "ColumnName 1",
  IsSelected: false
}, {
  ColumnID: 2,
  ColumnName: "ColumnName 2",
  IsSelected: true
}];

var viewModel = function() {
  var self = this;
  self.SelectionColumnList = ko.observableArray([]);

  // this property has the selected ColumnIds
  self.selectedItems = ko.computed(() => {
    // If you're using ES6 systax
    // return self.SelectionColumnList()
    //  .filter(column => column.IsSelected())
    //   .map(column => column.ColumnID);

    // out of the columns, get the ColumnIds with IsSelected as true
    return self.SelectionColumnList()
      .filter(function(column) {
        return column.IsSelected();
      })
      .map(function(column) {
        return column.ColumnID
      });
  });

  // gets triggered everytime checkbox is checked/unchecked
  self.selectedItems.subscribe(function() {
    console.log(self.selectedItems());
  });
}

// create a new instance of the viewmodel
var dynamicGridViewModel = new viewModel();

// loop through the columns and populate the observableArray
columns.forEach(function(columnInfo) {
  var selectionInfo = {};

  selectionInfo.ColumnID = columnInfo.ColumnID;
  selectionInfo.ColumnName = columnInfo.ColumnName;

  // this property must be an observable
  selectionInfo.IsSelected = ko.observable(columnInfo.IsSelected);

  dynamicGridViewModel.SelectionColumnList.push(selectionInfo);
})

ko.applyBindings(dynamicGridViewModel);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<ul class="list-group" data-bind="foreach: SelectionColumnList">
  <li class="list-group-item">
    <input type="checkbox" data-bind="checked: IsSelected" />
    <span data-bind="text: ColumnName"></span>
  </li>
</ul>
&#13;
&#13;
&#13;

Here's a fiddle for testing