Browse Source

Enhance DataResolverListener

pull/6802/head
Artur Arseniev 2 months ago
parent
commit
52964c6714
  1. 52
      packages/core/src/data_sources/model/DataResolverListener.ts

52
packages/core/src/data_sources/model/DataResolverListener.ts

@ -1,9 +1,11 @@
import { DataSourcesEvents, DataSourceListener } from '../types'; import { DataSourceListener } from '../types';
import { stringToPath } from '../../utils/mixins'; import { stringToPath } from '../../utils/mixins';
import { Model } from '../../common'; import { Model } from '../../common';
import EditorModel from '../../editor/model/Editor'; import EditorModel from '../../editor/model/Editor';
import DataVariable, { DataVariableType } from './DataVariable'; import DataVariable, { DataVariableType } from './DataVariable';
import { DataResolver } from '../types'; import { DataResolver } from '../types';
import DataRecord from './DataRecord';
import DataSource from './DataSource';
import { import {
DataCondition, DataCondition,
DataConditionOutputChangedEvent, DataConditionOutputChangedEvent,
@ -88,34 +90,52 @@ export default class DataResolverListener {
const path = dataVariable.getResolverPath(); const path = dataVariable.getResolverPath();
if (!path) return dataListeners; 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 [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(
dataListeners.push(this.createListener(ds.records, 'add remove reset', onChangeAndRewatch)); 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) { 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( dataListeners.push(
this.createListener(em.DataSources.all, 'add remove reset', onChangeAndRewatch), this.createListener(ds.records, 'add remove', onMatchingRecordChange),
this.createListener(em, `${DataSourcesEvents.path}:${normPath}`), this.createListener(ds.records, 'reset', onChangeAndRewatch),
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();
}
}),
); );
return dataListeners; 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() { private removeListeners() {
this.listeners.forEach((ls) => this.model.stopListening(ls.obj, ls.event, ls.callback)); this.listeners.forEach((ls) => this.model.stopListening(ls.obj, ls.event, ls.callback));
this.listeners = []; this.listeners = [];

Loading…
Cancel
Save