diff --git a/src/dataSources/index.ts b/src/dataSources/index.ts index 2b02e28f5..af266ef11 100644 --- a/src/dataSources/index.ts +++ b/src/dataSources/index.ts @@ -16,12 +16,12 @@ 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); - console.log('getValue', { context }); return get(context, key, defValue); } diff --git a/src/dataSources/model/DataRecord.ts b/src/dataSources/model/DataRecord.ts index 5cd514b1f..6e5e780fd 100644 --- a/src/dataSources/model/DataRecord.ts +++ b/src/dataSources/model/DataRecord.ts @@ -1,31 +1,59 @@ import { keys } from 'underscore'; import { Model } from '../../common'; -import { DataRecordProps } from '../types'; +import { DataRecordProps, DataSourcesEvents } from '../types'; import { DataRecords } from './DataRecords'; export class DataRecord extends Model { constructor(props: T, opts = {}) { super(props, opts); - this.on('change', (dr: DataRecord) => { - const { id, em } = this.dataSource; + this.on('change', this.handleChange); + } - const changed = dr.changedAttributes(); - keys(changed).forEach(prop => { - const path = this.getPath(prop); - console.log('TODO change to data:path:DS_ID.DR_ID.KEY ', path); - em.trigger(path); - }); - }); + get cl() { + return this.collection as unknown as DataRecords; } get dataSource() { - return (this.collection as unknown as DataRecords).dataSource; + return this.cl.dataSource; + } + + get em() { + return this.dataSource.em; } - getPath(prop?: string) { - const { dataSource, id } = this; + get index(): number { + return this.cl.indexOf(this); + } + + handleChange() { + const changed = this.changedAttributes(); + keys(changed).forEach(prop => this.triggerChange(prop)); + } + + /** + * Get path of the record + * @param {String} prop Property name to include + * @returns {String} + * @example + * const pathRecord = record.getPath(); + * // eg. 'SOURCE_ID.RECORD_ID' + * const pathRecord2 = record.getPath('myProp'); + * // eg. 'SOURCE_ID.RECORD_ID.myProp' + */ + getPath(prop?: string, opts: { useIndex?: boolean } = {}) { + const { dataSource, id, index } = this; const dsId = dataSource.id; const suffix = prop ? `.${prop}` : ''; - return `${dsId}.${id}${suffix}`; + return `${dsId}.${opts.useIndex ? index : id}${suffix}`; + } + + getPaths(prop?: string) { + return [this.getPath(prop), this.getPath(prop, { useIndex: true })]; + } + + triggerChange(prop?: string) { + const { dataSource } = this; + const data = { dataSource, dataRecord: this }; + this.getPaths(prop).forEach(path => this.em.trigger(`${DataSourcesEvents.path}:${path}`, { ...data, path })); } } diff --git a/src/dataSources/types.ts b/src/dataSources/types.ts index 1e3177ad3..fdc7d36e4 100644 --- a/src/dataSources/types.ts +++ b/src/dataSources/types.ts @@ -46,6 +46,13 @@ export enum DataSourcesEvents { */ update = 'data:update', + /** + * @event `data:path` Data record path update. + * @example + * editor.on('data:path:SOURCE_ID:RECORD_ID:PROP_NAME', ({ dataSource, dataRecord, path }) => { ... }); + */ + path = 'data:path', + /** * @event `data` Catch-all event for all the events mentioned above. * @example diff --git a/src/dom_components/view/ComponentDataVariableView.ts b/src/dom_components/view/ComponentDataVariableView.ts index 2ef6801de..8ed653eb4 100644 --- a/src/dom_components/view/ComponentDataVariableView.ts +++ b/src/dom_components/view/ComponentDataVariableView.ts @@ -1,3 +1,4 @@ +import { DataSourcesEvents } from '../../dataSources/types'; import ComponentDataVariable from '../model/ComponentDataVariable'; import ComponentView from './ComponentView'; @@ -5,7 +6,8 @@ export default class ComponentDataVariableView extends ComponentView this.postRender()); + const { path } = model.attributes; + this.listenTo(em, `${DataSourcesEvents.path}:${path}`, () => this.postRender()); } postRender() {