1
votes

I’m new working with ember.js and ember-light-table. I have a working example of a responsive table using ember-light-table. Below are the files that I’m using to generate this table. What I cannot figure out is how to show two different ember-light-table’s on the same route. Essentially when I build another table in the same fashion I have to set the model variable in the setupController hook on the route. However, I cannot set the model for both tables to the same model variable (hope that makes sense). What’s the best practice for setting up two ember-light-tables on the same route? Any help is greatly appriciated, thanks.

// Mixin

import Ember from 'ember';
import Table from 'ember-light-table';

const {
  Mixin,
  inject,
  isEmpty,
  set,
  get
} = Ember;

export default Mixin.create({
  store: inject.service(),

  page: 0,
  limit: 10,
  dir: 'asc',
  sort: 'HT_OverUnder',

  isLoading: false,
  canLoadMore: true,

  model: 'nba',
  columns: null,
  table: null,

  init() {
    this._super(...arguments);

    let table = new Table(get(this,'columns'), get(this,'model'), { enableSync: true });
    let sortColumn = table.get('allColumns').findBy('valuePath', get(this,'sort'));

    // Setup initial sort column
    if (sortColumn) {
      sortColumn.set('sorted', true);
    }

    set(this,'table',table);
  },

  fetchRecords() {
    console.log("fetch records: " );
    set(this,'isLoading', true);
    get(this,"store").query('nba', {per_page: get(this,"limit"), page: get(this,"page")}).then(records => {
      var model = get(this,'model');
      records.forEach(function(record){
        model.addObject(record._internalModel);
      });
      set(this,'isLoading', false);
      set(this,'canLoadMore', !isEmpty(records));
    });
  },

  actions: {
    onScrolledToBottom() {
      if (get(this,'canLoadMore')) {
        this.incrementProperty('page');
        this.fetchRecords();
      }
    },

    onColumnClick(column) {
      if (column.sorted) {
        this.setProperties({
          dir: column.ascending ? 'asc' : 'desc',
          sort: column.get('valuePath'),
          canLoadMore: true,
          page: 0
        });
        get(this,'model').clear();
      }
    }
  }
});

// Component.js

import Ember from 'ember';
import NbaTable from '../mixins/nba-table';
import _ from 'underscore';
import moment from 'moment';

const {
  Component, computed, inject: { service }, get, set, run, $
} = Ember;

export default Component.extend(NbaTable, {
  successMessage: null,
  errorMessage: null,
  session: service('session'),
  userData: Ember.computed('session.session.content.authenticated', function() {
    var authenticator = Ember.getOwner(this).lookup('authenticator:jwt'),
        session = this.get('session.session.content.authenticated'),
        tokenData = {};

    if(session && Object.keys(session).length > 0) {
      tokenData = authenticator.getTokenData(session.token);
    }

    return tokenData.email;
  }),

  model: [],
  table: null,
  picks: [],
  currentGame: {},

  actions: {
    onAfterResponsiveChange(matches) {
      if (matches.indexOf('jumbo') > -1) {
        this.get('table.expandedRows').setEach('expanded', false);
      }
    }
  },

  columns: computed(function() {
    return [{
      label: 'Gametime',
      valuePath: 'gametime',
      sortable: true,
      align: 'center',
    },{
      label: 'Away Team',
      valuePath: 'imgAT',
      sortable: true,
      align: 'center',
      cellComponent: 'awayteam-image'
    }, {
      label: 'Home Team',
      valuePath: 'imgHT',
      sortable: true,
      align: 'center',
      cellComponent: 'hometeam-image'
    }, {
      label: 'Home Spread',
      valuePath: 'spreadDisplay',
      sortable: true,
      align: 'center',
      cellComponent: 'ht-spread'
    }, {
      label: 'Game Total',
      valuePath: 'HT_OverUnder',
      sortable: true,
      align: 'center',
      cellComponent: 'ht-total'
    }, {
      label: 'Info',
      align: 'center',
      sortable: false,
      width: '50px',
      cellComponent: 'info-modal'
    }, {
      label: 'Select Picks',
      align: 'center',
      sortable: false,
      width: '200px',
      cellComponent: 'toggle-switch'
    }];
  })

});

// Route.js

import Ember from 'ember';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';

const {
  Route,
  RSVP: { hash },
  get
} = Ember;

export default Route.extend(AuthenticatedRouteMixin, {
  model() {
    return hash({
      nba: this.store.findAll('nba'),
      ncaa: this.store.findAll('ncaa')
    });
  },

  setupController(controller, model) {
    this._super(...arguments);

    /** I know this is wrong, but don’t know how to fix it **/
    controller.set('model', model.nba );
    controller.set('model', model.ncaa );
  },

  actions: {
    invalidateSession: function() {
      get(this,'session').invalidate();
    }
  }

});

// Template/Component

{{#light-table table tableClassNames="table table-striped table-hover"
  responsive=true
  onAfterResponsiveChange=(action 'onAfterResponsiveChange') 
  as |t|
}}

  {{t.head
    onColumnClick=(action 'onColumnClick')
    iconAscending='fa fa-sort-asc'
    iconDescending='fa fa-sort-desc'
  }}

  {{#t.body
    canSelect=false
    expandOnClick=false
    as |body|
  }}
    {{#body.expanded-row as |row|}}
      {{responsive-expanded-row table=table row=row}}
    {{/body.expanded-row}}

    {{#if isLoading}}
      {{#body.loader}}
        {{table-loader}}
      {{/body.loader}}
    {{/if}}
  {{/t.body}}

  {{#t.foot as |columns|}}
    <tr style="background-color: lightgray">
      <td class="align-center" colspan={{columns.length}}>
        <h5 class="pull-left">Current Games</h5>
      </td>
    </tr>
  {{/t.foot}}

{{/light-table}}

  {{!-- Error Messages --}}
  {{#if errorMessage }}
    <div class="alert alert-danger error">
      <strong>Erorr: </strong> {{errorMessage}}
    </div>
  {{/if}}
  {{#if successMessage }}
    <div class="alert alert-success success">
      <strong>Success: </strong> {{successMessage}}
    </div>
  {{/if}}
1

1 Answers

1
votes

It may be late, but this answer might help someone else. Also, I don't know if this is a best practice, but this worked for me.

Mixin:

import Table from 'ember-light-table';

export default Ember.Mixin.create({
  // other Properties
  fetchRecords: function() {
    this.get('store')
      .query(this.get('modelName'), {queryObjcet})
      .then((records) => {
        this.get('model').pushObjects(records.toArray());
      })
      .finally(() => {
       this.set('isLoading', false);
      });
  },

  // Other actions
});

Component 1:

import Ember from 'ember';
import DynamicTable from 'mixins/table-dynamic';

export default Ember.Component.extend(DynamicTable,{
  modelName:'firstModel',

  columns: [...]

  //Other actions
});

Component 2:

import Ember from 'ember';
import DynamicTable from 'mixins/table-dynamic';

export default Ember.Component.extend(DynamicTable,{
  modelName:'secondModel',

  columns: [...]

  //Other actions
});

Likewise we'll be able to extend the same mixin over many table as we like.