diff --git a/src/data_sources/index.ts b/src/data_sources/index.ts index 0fbf8c503..6075a04db 100644 --- a/src/data_sources/index.ts +++ b/src/data_sources/index.ts @@ -1,8 +1,6 @@ import { ItemManagerModule, ModuleConfig } from '../abstract/Module'; -import { AddOptions, ObjectAny, RemoveOptions } from '../common'; +import { AddOptions, RemoveOptions } from '../common'; import EditorModel from '../editor/model/Editor'; -import { get, stringToPath } from '../utils/mixins'; -import DataRecord from './model/DataRecord'; import DataSource from './model/DataSource'; import DataSources from './model/DataSources'; import { DataSourceProps, DataSourcesEvents } from './types'; @@ -58,41 +56,4 @@ export default class DataSourceManager extends ItemManagerModule { - acc[ds.id] = ds.records.reduce((accR, dr, i) => { - accR[i] = dr.attributes; - accR[dr.id || i] = dr.attributes; - return accR; - }, {} as ObjectAny); - return acc; - }, {} as ObjectAny); - } - - fromPath(path: string) { - const result: [DataSource?, DataRecord?, string?] = []; - const [dsId, drId, ...resPath] = stringToPath(path || ''); - const dataSource = this.get(dsId); - const dataRecord = dataSource?.records.get(drId); - dataSource && result.push(dataSource); - - if (dataRecord) { - result.push(dataRecord); - resPath.length && result.push(resPath.join('.')); - } - - return result; - } } diff --git a/src/data_sources/model/DataRecords.ts b/src/data_sources/model/DataRecords.ts index 2bdfd3d06..b4e94d0e4 100644 --- a/src/data_sources/model/DataRecords.ts +++ b/src/data_sources/model/DataRecords.ts @@ -1,3 +1,4 @@ +import { Model } from 'backbone'; import { AddOptions, Collection } from '../../common'; import { DataRecordProps } from '../types'; import DataRecord from './DataRecord'; diff --git a/src/data_sources/model/DataSource.ts b/src/data_sources/model/DataSource.ts index 333eac737..b953f429b 100644 --- a/src/data_sources/model/DataSource.ts +++ b/src/data_sources/model/DataSource.ts @@ -51,7 +51,13 @@ export default class DataSource extends Model { } getRecord(id: string | number): DataRecord | undefined { - return this.records.get(id); + const onRecordRead = this.transformers.onRecordRead; + const record = this.records.get(id); + if (record && onRecordRead) { + return onRecordRead({ record }); + } + + return record; } getRecords() { diff --git a/src/data_sources/model/StyleDataVariable.ts b/src/data_sources/model/StyleDataVariable.ts index 99e4848cb..e0d33bcec 100644 --- a/src/data_sources/model/StyleDataVariable.ts +++ b/src/data_sources/model/StyleDataVariable.ts @@ -30,9 +30,13 @@ export default class StyleDataVariable extends Model { } } - onDataSourceChange(model: any) { + onDataSourceChange() { const { path } = this.attributes; - const newValue = get(model, stringToPath(path).join('.'), ''); + const [dsId, drId, key] = stringToPath(path); + const ds = this?.em?.DataSources.get(dsId); + const dr = ds && ds.getRecord(drId); + const newValue = dr?.get(key); + this.set({ value: newValue }); } } diff --git a/src/dom_components/model/ComponentDataVariable.ts b/src/dom_components/model/ComponentDataVariable.ts index eab0bd38e..b60927a56 100644 --- a/src/dom_components/model/ComponentDataVariable.ts +++ b/src/dom_components/model/ComponentDataVariable.ts @@ -1,4 +1,4 @@ -import { toLowerCase } from '../../utils/mixins'; +import { stringToPath, toLowerCase } from '../../utils/mixins'; import Component from './Component'; import { ToHTMLOptions } from './types'; @@ -17,7 +17,11 @@ export default class ComponentDataVariable extends Component { getInnerHTML(opts: ToHTMLOptions & { keepVariables?: boolean } = {}) { const { path, value } = this.attributes; - return opts.keepVariables ? path : this.em.DataSources.getValue(path, value); + const [dsId, drId, key] = stringToPath(path); + const ds = this.em.DataSources.get(dsId); + const dr = ds && ds.getRecord(drId); + + return opts.keepVariables ? path : dr ? dr.get(key) : value; } static isComponent(el: HTMLElement) { diff --git a/src/dom_components/view/ComponentDataVariableView.ts b/src/dom_components/view/ComponentDataVariableView.ts index 102638669..7a1b71c66 100644 --- a/src/dom_components/view/ComponentDataVariableView.ts +++ b/src/dom_components/view/ComponentDataVariableView.ts @@ -16,8 +16,11 @@ export default class ComponentDataVariableView extends ComponentView extends Model dataListeners.forEach(ls => this.listenTo(ls.obj, ls.event, () => { - const newValue = em?.DataSources.getValue(normPath, dataVar.get('value')); + const [dsId, drId, keyPath] = stringToPath(path); + const ds = em?.DataSources.get(dsId); + const dr = ds && ds.records.get(drId); + const newValue = dr && dr.get(keyPath); + this.updateStyleProp(styleProp, newValue); }) ); @@ -165,8 +169,13 @@ export default class StyleableModel extends Model const resolvedStyle = { ...style }; keys(resolvedStyle).forEach(key => { const styleValue = resolvedStyle[key]; + if (styleValue instanceof StyleDataVariable) { - const resolvedValue = this.em?.DataSources.getValue(styleValue.get('path'), styleValue.get('value')); + const [dsId, drId, keyPath] = stringToPath(styleValue.get('path')); + const ds = this.em?.DataSources.get(dsId); + const dr = ds && ds.records.get(drId); + const resolvedValue = dr && dr.get(keyPath); + resolvedStyle[key] = resolvedValue || styleValue.get('value'); } }); diff --git a/test/specs/data_sources/index.ts b/test/specs/data_sources/index.ts index 74de3bf38..3266ec865 100644 --- a/test/specs/data_sources/index.ts +++ b/test/specs/data_sources/index.ts @@ -126,7 +126,7 @@ describe('DataSourceManager', () => { }); }); - describe.only('Transformers', () => { + describe('Transformers', () => { let fixtures: HTMLElement; let cmpRoot: ComponentWrapper; @@ -225,6 +225,42 @@ describe('DataSourceManager', () => { const result = ds.getRecord('id1')?.get('content'); expect(result).toBe('I LOVE GRAPES'); }); + + test('onRecordRead', () => { + const testDataSource: DataSourceProps = { + id: 'test-data-source', + records: [], + transformers: { + onRecordRead: ({ record }) => { + const content = record.get('content'); + + return record.set('content', content.toUpperCase(), { avoidTransformers: true }); + }, + }, + }; + dsm.add(testDataSource); + + const cmp = cmpRoot.append({ + tagName: 'h1', + type: 'text', + components: [ + { + type: 'data-variable', + value: 'default', + path: 'test-data-source.id1.content', + }, + ], + })[0]; + + const ds = dsm.get('test-data-source'); + ds.addRecord({ id: 'id1', content: 'i love grapes' }); + + const el = cmp.getEl(); + expect(el?.innerHTML).toContain('I LOVE GRAPES'); + + const result = ds.getRecord('id1')?.get('content'); + expect(result).toBe('I LOVE GRAPES'); + }); }); test('add DataSource with records', () => {