Knockout: Selectable table rows without extending

2019-04-26 17:29发布

I have the following table template that is rendered through knockout:

            <table class="gv" data-bind="visible: products().length > 0">
                <thead>
                    <th>Type</th>
                    <th>Name</th>
                </thead>
                <tbody data-bind="foreach: products">
                    <tr data-bind="click: $root.selectProduct">
                        <td data-bind="text: type"></td>
                        <td data-bind="text: name"></td>
                    </tr>
                </tbody>
            </table>

Now I want to make the rows clickable and want to assign a css class if a row is selected. Only 1 (!) row could be selected at a time, so others have to be unchecked.

The simplest way would be to extend my model (product class) with a selected property but this would destroy my 1:1 mapping with the server side.

How should I solve this issue? How would you handle this?

标签: knockout.js
3条回答
▲ chillily
2楼-- · 2019-04-26 17:51

You could add a hidden radio button group to the table, and when the row is selected calling selectProduct the radio button is selected.

This ensures that only one row is selected.

Alternatively you could write a custom binding using the jQuery .data() to specify the selected row.

查看更多
再贱就再见
3楼-- · 2019-04-26 17:54

I created a jsfiddle for myself and you, since the answered one doesn't actually work

The key is a combination of using an observable for the selected item and utilizing knockout's automatic binding of the current item for click events:

ViewModel = function() {
  self = this;
  this.selectedItem = ko.observable();
  this.items = ko.observableArray();

}
ViewModel.prototype.selectItem = function(item) {
  self.selectedItem(item);
}

and the html:

  <ul class="results__container">
    <!-- ko foreach: items -->
    <li class="results__item" data-bind="css: { 'results__item--selected': $root.selectedItem() === $data }, click: $root.selectItem">
      <span data-bind="text: Title"></span>
    </li>
    <!-- /ko -->
  </ul>

http://jsfiddle.net/enorl76/9hLgfzot/

查看更多
We Are One
4楼-- · 2019-04-26 17:55

This was my final solution now, no extra hidden radio buttons:

<tr data-bind="click: $root.selectProduct, css: { 'active-row': $root.selectedProduct() === $data }">

And the selectedProduct implementation within the ViewModel:

function AppViewModel() {
    // Private
    var self = this;

    // Public Properties
    self.selectedProduct = ko.observable();
查看更多
登录 后发表回答