|
|
|
@ -1,9 +1,11 @@ |
|
|
|
import { DataSourcesEvents, DataSourceListener } from '../types'; |
|
|
|
import { DataSourceListener } from '../types'; |
|
|
|
import { stringToPath } from '../../utils/mixins'; |
|
|
|
import { Model } from '../../common'; |
|
|
|
import EditorModel from '../../editor/model/Editor'; |
|
|
|
import DataVariable, { DataVariableType } from './DataVariable'; |
|
|
|
import { DataResolver } from '../types'; |
|
|
|
import DataRecord from './DataRecord'; |
|
|
|
import DataSource from './DataSource'; |
|
|
|
import { |
|
|
|
DataCondition, |
|
|
|
DataConditionOutputChangedEvent, |
|
|
|
@ -88,34 +90,52 @@ export default class DataResolverListener { |
|
|
|
const path = dataVariable.getResolverPath(); |
|
|
|
if (!path) return dataListeners; |
|
|
|
|
|
|
|
const normPath = stringToPath(path || '').join('.'); |
|
|
|
const dsAll = em.DataSources.all; |
|
|
|
const [dsId, drKey, ...propPathParts] = stringToPath(path || ''); |
|
|
|
const [ds, dr] = em.DataSources.fromPath(path!); |
|
|
|
const isIndexPath = !!ds && drKey !== undefined && ds.isRecordIndex(drKey); |
|
|
|
const onMatchingSourceChange = (ds: DataSource) => ds.id === dsId && onChangeAndRewatch(); |
|
|
|
|
|
|
|
if (ds) { |
|
|
|
dataListeners.push(this.createListener(ds.records, 'add remove reset', onChangeAndRewatch)); |
|
|
|
dataListeners.push( |
|
|
|
this.createListener(dsAll, 'add remove', onMatchingSourceChange), |
|
|
|
this.createListener(dsAll, 'reset', onChangeAndRewatch), |
|
|
|
); |
|
|
|
|
|
|
|
if (!ds) return dataListeners; |
|
|
|
|
|
|
|
if (drKey === undefined) { |
|
|
|
dataListeners.push(this.createListener(ds.records, 'add remove reset change', onChangeAndRewatch)); |
|
|
|
return dataListeners; |
|
|
|
} |
|
|
|
|
|
|
|
if (dr) { |
|
|
|
dataListeners.push(this.createListener(dr, 'change')); |
|
|
|
const onRecordChange = (record: DataRecord) => this.onRecordChange(record, propPathParts); |
|
|
|
dataListeners.push(this.createListener(dr, 'change', onRecordChange)); |
|
|
|
} |
|
|
|
|
|
|
|
if (isIndexPath) { |
|
|
|
dataListeners.push(this.createListener(ds.records, 'add remove reset', onChangeAndRewatch)); |
|
|
|
return dataListeners; |
|
|
|
} |
|
|
|
|
|
|
|
const onMatchingRecordChange = (record: DataRecord) => `${record.id}` === `${drKey}` && onChangeAndRewatch(); |
|
|
|
dataListeners.push( |
|
|
|
this.createListener(em.DataSources.all, 'add remove reset', onChangeAndRewatch), |
|
|
|
this.createListener(em, `${DataSourcesEvents.path}:${normPath}`), |
|
|
|
this.createListener(em, DataSourcesEvents.path, ({ path: eventPath }: { path: string }) => { |
|
|
|
if ( |
|
|
|
// Skip same path as it's already handled be the listener above
|
|
|
|
eventPath !== path && |
|
|
|
eventPath.startsWith(path) |
|
|
|
) { |
|
|
|
this.onChange(); |
|
|
|
} |
|
|
|
}), |
|
|
|
this.createListener(ds.records, 'add remove', onMatchingRecordChange), |
|
|
|
this.createListener(ds.records, 'reset', onChangeAndRewatch), |
|
|
|
); |
|
|
|
|
|
|
|
return dataListeners; |
|
|
|
} |
|
|
|
|
|
|
|
private onRecordChange(record: DataRecord, propPath: string[]) { |
|
|
|
const changed = Object.keys(record.changedAttributes() || {}); |
|
|
|
const [rootProp] = propPath; |
|
|
|
|
|
|
|
if (!changed.length || changed.includes('id') || !propPath.length || (rootProp && changed.includes(rootProp))) { |
|
|
|
this.onChange(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private removeListeners() { |
|
|
|
this.listeners.forEach((ls) => this.model.stopListening(ls.obj, ls.event, ls.callback)); |
|
|
|
this.listeners = []; |
|
|
|
|