Пользовательские типы данных для атрибутов объектов описываются в папке app\transforms и являются расширением DS.Transform.

Обязательны для указания базовые методы преобразования serialize и deserialize.

// app/transforms/ember-flexberry-dummy-text.js

import DS from 'ember-data';

let FlexberryTextTransform = DS.Transform.extend({
  deserialize: function(serialized) {
    return isNone(serialized) ? null : String(serialized);
  },

  serialize: function(deserialized) {
    return isNone(deserialized) ? null : String(deserialized);
  },
});

export default FlexberryTextTransform;

Далее указываются методы которые используются в технологии, на списковых формах и запросах данных к бекенду. Все методы указываются внутри reopenClass:

  • conditionsForFilter: перечень условий для списковой формы. Возращает JSON;
/**
  Builds conditions for filter

  @example
    ```javascript
    conditionsForFilter()
    ```

  @method conditionsForFilter
  @return JSON conditions for filter.
*/
conditionsForFilter() {
  return {
    'eq': 'Text equal',
    'neq': 'Text not equal',
    'like': 'Text like',
    'nlike': 'Text not like',
    'hasAttr': 'Text has attribute',
  };
}
  • predicateForFilter: сформировать ограничение по фильтру. Принимает параметр filter, содержащий атрибуты name, condition, pattern. Имя, условие и значение соответственно. Возвращает предикат, то ограничение которое применится при указании соответствующего фильтра.
/**
  Builds predicate for filter

  @example
    ```javascript
    predicateForFilter(filter)
    ```

  @method predicateForFilter
  @param {Object} filter Object (`{ name, condition, pattern }`) with parameters for filter.
  @return {BasePredicate|null} Predicate to filter through.
*/
predicateForFilter(filter) {
  if (filter.condition) {
    switch (filter.condition) {
      case 'like':
        return new StringPredicate(filter.name).contains(filter.pattern || '');
      case 'nlike':
        return new NotPredicate(new StringPredicate(filter.name).contains(filter.pattern || ''));
      case 'hasAttr':
          return new StringPredicate(filter.name).contains('"' + filter.pattern + '":' || '');
      default:
        return new SimplePredicate(filter.name, filter.condition, filter.pattern || null);
    }
  }

  return null;
}
  • componentForFilter: компонент который будет использоваться для ввода значения фильтрации. Возвращает JSON с параметрами name и properties.
/**
  Builds component for filter

  @example
    ```javascript
    componentForFilter()
    ```

  @method componentForFilter
  @return JSON component for filter.
*/
componentForFilter() {
  return { name: 'flexberry-textbox', properties: { class: 'compact fluid' } };
}
  • getOdataValue: Получить значение для ограничения OData. Используется при запросе к бекенду.
/**
  Get OData value

  @example
    ```javascript
    getOdataValue(predicateValue)
    ```

  @method getOdataValue
  @param {Object} predicateValue Raw object value.
  @return {String} OData value.
*/
getOdataValue(predicateValue) {
  return `'${String(predicateValue).replace(/'/g, `''`)}'`;
}

OData

Если в одата еще не добавлен функционал по использованию getOdataValue, то необходимо добавить инициализатор с переопределением функции _processConstForODataSimplePredicateByType

//app/initializers/odata-adapter-custom.js

import { isNone } from '@ember/utils';
import Application from '@ember/application';
import ODataAdapter from 'ember-flexberry-data/query/odata-adapter';
import getSerializedDateValue from 'ember-flexberry-data/utils/get-serialized-date-value';

export function initialize() {
  ODataAdapter.prototype._processConstForODataSimplePredicateByType = function (predicate, predicateValue, valueType) {
    let appContainer = Application.NAMESPACES.find(x => x.backendUrl && x.__container__).__container__;
    let transformInstance = appContainer.lookup('transform:' + valueType);
    let transformClass = !isNone(transformInstance) ? transformInstance.constructor : null;

    if (transformClass && transformClass.getOdataValue) {
      return transformClass.getOdataValue(predicateValue);
    }

    return valueType === 'string'
      ? `'${String(predicateValue).replace(/'/g, `''`)}'`
      : ((valueType === 'date' || (valueType === 'object' && predicateValue instanceof Date))
        ? getSerializedDateValue.call(this._store, predicateValue, predicate.timeless)
        : predicateValue);
  }
}

export default {
  name: 'odata-adapter-custom',
  initialize
};

Перейти