javascript - knockout 中的复选框 onclick 不会更新 View 模型

标签 javascript java knockout.js

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

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

 <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>

更新:

我的 View 模型是

  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);

最佳答案

您不需要 onclick 事件。您只需使用 checked binding 即可实现此目的:

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());
<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>

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

Knockout 的伟大之处在于,它不仅允许 primitive types例如 checkedValue 的字符串、数字或 boolean 值,但也包括对象。如果您希望将整个Column对象填充到chosenItems中,那么您可以像这样设置checkedValue:

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

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

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

更新:

您正在使用对象文字作为您的 View 模型。我建议您创建 viewModel 函数并使用 new运算符(operator)。如果您想将 checked 绑定(bind)到 Column 的 boolean 属性,那么您可以创建一个 computed属性并订阅该计算属性:

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);
<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>

Here's a fiddle for testing

关于javascript - knockout 中的复选框 onclick 不会更新 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47331161/

相关文章:

javascript - 如何使用 knockout 数据和 "external"数据进行计算来过滤数据

java - 解析 XML 时出错 : unbound prefix (External library)

java - Android 错误 - 致命异常 : main

javascript - knockout JS 将值传递给函数

javascript - NodeJS : invalid array length Allocation failed - JavaScript heap out of memory

java - 如何增加JVM的堆大小

javascript - 如何隐藏验证消息

javascript - 如何将 React 状态绑定(bind)到 RxJS 可观察流?

javascript - REACT - 渲染组件时出错

javascript - 在网页上查找一个单词并向其添加跨度