mercredi 16 janvier 2019

How can I use a model in a component in isolation but maintain a one-way bind for model refreshes?

I currently have component that displays a table of results abse don the m odel passed into it:

\\pagedContent is a computed property of the model


The table updates its contents as various filters are selected via query params. I've bee trying to implement some 'sort on click' behaviour to the table headings with the following code:

    import Component from '@ember/component';
    import {
      computed
    } from '@ember/object';

    export default Component.extend({

      model: null,
      init() {
        this._super(...arguments);
        this.dataSorting = ['total_users']
        this.dataSortingDesc = ['total_users:desc']
      },

      sortedDataDesc: computed.sort('unsortedData', 'dataSortingDesc'),
      sortedData: computed.sort('unsortedData', 'dataSorting'),
      unsortedData: computed('model', function () {
        return this.get('model');
      }),

      actions: {
        columnsort(property) {
          if (!this.get('tableSorted')) {

            this.set('dataSortingDesc', [`${property}:desc`])
            this.set('model', this.get('sortedDataDesc'))
            this.set('tableSorted', true)

          } else {
            this.set('dataSorting', [property])
            this.set('displayModel', this.get('sortedData'))
            this.set('model', null)
          }
        },
      }
    });

The sorting works as expected but I have a problem due to the two way binding of the model. Other components on the template also uses the model and when the data in the table is sorted, it creates all kinds of problems with those components.

I tried to create a seperate 'copy' of the model using a computed property like follows:

  \\a new property
  displayModel: computed('model', function () {
    return this.get('model');
  }),
  sortedDataDesc: computed.sort('unsortedData', 'dataSortingDesc'),
  sortedData: computed.sort('unsortedData', 'dataSorting'),
  unsortedData: computed('model', function () {
    return this.get('model');
  }),

  actions: {
    columnsort(property) {
      if (!this.get('tableSorted')) {

        this.set('dataSortingDesc', [`${property}:desc`])
        this.set('model', this.get('sortedDataDesc'))
        this.set('tableSorted', true)

      } else {
        this.set('dataSorting', [property])
        this.set('displayModel', this.get('sortedData'))
        this.set('model', null)
      }
    },

The table then iterates over displayModel to create itself. This produces a behaviour where the columns sort but then the display 'freezes' once a column heading is clicked and does not update as the underlying model updates. In this case, I can see from my other components that the model continues to update as new filters are applied.

I was also unsuccessful using a oneWay and didUpdateAttrs implementation. I'd be grateful for any advice.




Aucun commentaire:

Enregistrer un commentaire