EmberJS - 包含多个复选框的表格 - 如何保存'已检查'分页状态

时间:2017-05-14 23:04:47

标签: ember.js ember-data ember-cli

这是我的组件的模板 的排序表-checkbox.hbs

<table class="table table-checkbox" data-page-length="{{dataPageLength}}">
  <thead>
    <tr>
      <th>&nbsp;</th>
      {{#each-in columns as |prop value| }}
        <th
          class="{{if (or (eq (get sortingStatus prop) '')
                          (eq (get sortingStatus prop) 'asc')
                          (eq (get sortingStatus prop) 'desc')) 'sorting'}} w25p {{get sortingStatus prop}}"
          {{action 'toggleSorting' prop}}>
          {{#if value.title}}
            {{value.title}}
          {{else}}
            {{value}}
          {{/if}}
        </th>
      {{/each-in}}
    </tr>
  </thead>
  <tbody>
  {{#each data as |item|}}
    <tr>
      <td>
        <div class="">
          {{input
              type='checkbox'
              checked=item.checked
              change=(action 'chooseItem' item)}}

        </div>
      </td>
      {{#each-in columns as |prop value| }}
        <td>
          {{#collection- value=(get item prop) field=value.field as |col|}}
            {{#number-format isNumber=(eq value.type 'number') value=col as |val|}}
              {{#if value.linkable}}
                {{#link-to value.linkable.route (get item value.linkable.paramField)}}
                  {{value.prefix}}
                  {{val}}
                {{/link-to}}
              {{else}}
                {{value.prefix}}
                {{val}}
              {{/if}}
            {{/number-format}}
          {{/collection-}}
        </td>
      {{/each-in}}
    </tr>
  {{/each}}
  </tbody>
</table>

<p>Your Selected Items:</p>
<ul>
  {{#each selectedItems as |item|}}
    <li>{{item.title}}</li>
  {{else}}
    <em>No items selected</em>
  {{/each}}
</ul>

{{checked}}


{{yield}}

这是我的组件 的排序表-checkbox.js

import Ember from 'ember';

/**
 * Table component
 *
 * Allows to render dynamic tables with sorting where items are displayed as
 * checkboxes
 *
 * Header titles of table should passed as ``columns`` arg to the component.
 *
 * columns: {
 *   title: {
 *     title: 'Game Title',
 *     sorting: 'title',
 *     linkable: {
 *       route: 'home.cabinet.developer.games.game',
 *       paramField: 'game_uid',
 *     },
 *   },
 *   genres: {
 *     title: 'Genre',
 *   },
 *   amount: {
 *     title: 'Ad Revenue Earned',
 *     prefix: '$',
 *     type: 'number',
 *     sorting: 'amount'
 *   },
 *   platforms_data: {
 *     title: 'Platform',
 *     collection: true,
 *     field: 'title',
 *   },
 *   ages_data: {
 *     title: 'Ages',
 *     collection: true,
 *     field: 'value',
 *   },
 * },
 *
 * Example of using of this component
 *
 * {{sortable-table data=model.games.results columns=columns sorting=sorting}}
 *
 * @class SortingTableComponent
 * @module components/sortable-table
 * @extends Ember.Component
 * @public
 */
export default Ember.Component.extend({

  /**
   * Sorting status
   *
   * @property sortingStatus
   * @type {Object}
   * @default null
   * @public
   */
  sortingStatus: null,

  /**
   * Avoid sharing state between components
   *
   * @method init
   * @return {undefined}
   * @public
   */
  init() {
    this._super(...arguments);
    this.set('sortingStatus', {});
    this.selectedItems = [];
    this.checked=false;
  },

  /**
   * Fill ``sortingStatus`` object with reset statuses
   *
   * @method willInsertElement
   * @return {undefined}
   * @public
   */
  willInsertElement() {
    const columns = this.get('columns');

    for (const element in columns) {
      if (columns[element].sorting) {
        this.set(`sortingStatus.${element}`, '');
      }
    }
  },

  actions: {

    /**
     * Toggle sorting
     *
     * @method toggleSorting
     * @param prop {String} name of property
     * @return {boolean} false if this property doesn't exist in ``sorting`` object
     * @public
     */
    toggleSorting(prop) {
      // If ``prop`` property doesn't exist in ``sorting`` object, return false
      if (!(prop in this.get('sortingStatus'))) {
        return false;
      }

      // Reset another properties sorting state
      for (const element in this.get('sortingStatus')) {
        if (element !== prop) {
          this.set(`sortingStatus.${element}`, '');
        }
      }

      // Set asc if starting state, desc if asc and starting state if desc
      if (this.get(`sortingStatus.${prop}`) === '') {
        this.set(`sortingStatus.${prop}`, 'asc');
      } else if (this.get(`sortingStatus.${prop}`) === 'asc') {
        this.set(`sortingStatus.${prop}`, 'desc');
      } else {
        this.set(`sortingStatus.${prop}`, '');
      }

      // Sending action
      this.sendAction('action', this.get(`columns.${prop}.sorting`), this.get(`sortingStatus.${prop}`));

      return true;
    },

    chooseItem(item, e) {
      const added = e.target.checked;
      this.set('checked', added);
      if (added) {
        item.checked=true;
        this.get('selectedItems').pushObject(item);
      }
      else {
        this.get('selectedItems').removeObject(item);
      }
    },
  },
});

enter image description here

因此,当我浏览页面时,应用程序API调用查询接下来要显示的5个项目,当我回到第1页时,我没有item.checked状态 - 因为项目是来自API调用的新对象,因此,我没有在 chooseItem 操作中设置 .checked 属性。

如何解决这个问题?

也许有一种动态方法可以检查是否可以设置复选框的已选中属性?

1 个答案:

答案 0 :(得分:4)

由于您未在后端使用正确的选中字段保存模型,因此不会保存这些更改。我建议两种方法动态计算复选框的选中状态:

  1. 速度快。您可以create a custom helper检查该元素是否在数组中。或者您可以使用提供此类帮助的any existing addon。然后你可以在 sortable-table-checkbox.hbs
  2. 中写下这样的东西
    
        {{input type='checkbox' 
        checked=(array-contains selectedItems item.id property='id') 
        change=(action 'chooseItem' item)}}
    
    
    1. 您可以创建一个组件table-row,并在{strong> sortable-table-checkbox.hbs 中移动<tr></tr>中的所有内容。该组件将以itemselectedItems作为参数。然后您可以使用Ember计算属性:
    2. 
            //table-row.js
            // ...
            isChecked: Ember.computed('item.id', 'selectedItems.length', function() {
                const itemId = this.get('item.id');
                const selectedItems = this.get('selectedItems');
                return selectedItems.some(el => el.get('id') === itemId);
            })
            // ...
      
      
      
          //table-row.hbs
          {{input type='checkbox'
                  checked=isChecked
                  change=(action 'chooseItem' item)}}