MiguelMadero/ember-view-state

View on GitHub
addon/mixins/view-state.js

Summary

Maintainability
A
0 mins
Test Coverage
import Ember from 'ember';

const {on, computed, inject } = Ember;

/***
 * Turns a mix of string and objects into objects with key/value so we can use consistently.
 */
var adjustPropertyDefinitions = function(properties) {
  return properties.map(function(propertyDefinition) {
    if (typeof propertyDefinition === 'string') {
      return {
        mixeePropertyName: propertyDefinition,
        persistedPropertyName: propertyDefinition
      };
    }
    var key = Object.keys(propertyDefinition)[0];
    return {
      mixeePropertyName: key,
      persistedPropertyName: propertyDefinition[key]
    };
  });
};
/***
 * Synchronizes mixee properties with persisted user ViewState.
 * some of the API is inspired by concept's used by Ember's [query-params]
 * (http://emberjs.com/guides/routing/query-params/), please read it for a deeper understanding
 */
export default Ember.Mixin.create({
  viewStateRepository: inject.service(),
  /***
   * key used to uniquely identify the persisted properties.
   * Required, must be defined by mixee
   */
  viewStateKey: null,
  /***
   * List of properties to persist
   * Specify an array with strings or objects. If using an object, the key refers to the mixee property
   * and the string value to the persisted property
   * ```
   * viewStateKey: ['sort', 'group', {componentProperty: 'persistedProperty'}]
   * ```
   * To specify a default value, simply define it in the mixee.
   * For more information see [query-params Map a controller's property to a different query param
   * key](http://emberjs.com/guides/routing/query-params/)
   */
  viewStateProperties: computed(function() {
    return [];
  }),

  loadViewState: on('init', function() {
    const viewState = this.get('viewStateRepository').getViewStateFor(this.get('viewStateKey'));
    const propertyDefinitions = adjustPropertyDefinitions(this.get('viewStateProperties'));

    propertyDefinitions.forEach(propertyDefinition=> {
      if (viewState.hasOwnProperty(propertyDefinition.persistedPropertyName)) {
        // If we have a persisted value, we set it in the mixee. Otherwise, leave the default
        this.set(propertyDefinition.mixeePropertyName,
          viewState[propertyDefinition.persistedPropertyName]);
      }
    });
  }),

  persistViewState: on('willDestroyElement', function() {
    const viewState = this.get('viewStateRepository').getViewStateFor(this.get('viewStateKey'));
    const propertyDefinitions = adjustPropertyDefinitions(this.get('viewStateProperties'));

    propertyDefinitions.forEach(propertyDefinition=> {
      Ember.set(viewState, propertyDefinition.persistedPropertyName,
        this.get(propertyDefinition.mixeePropertyName));
    });
    viewState.lastUpdatedAt = new Date();
    this.get('viewStateRepository').flush();
  })
});