Browse Source

Refactor data variable listeners to a generic dynamic variable (#6229)

Co-authored-by: Artur Arseniev <artur.catch@hotmail.it>
pull/6244/head
mohamed yahia 1 year ago
committed by GitHub
parent
commit
45da189c08
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      packages/core/src/css_composer/model/CssRule.ts
  2. 50
      packages/core/src/data_sources/model/DataVariableListenerManager.ts
  3. 6
      packages/core/src/data_sources/view/ComponentDataVariableView.ts
  4. 4
      packages/core/src/dom_components/model/Component.ts
  5. 24
      packages/core/src/domain_abstract/model/StyleableModel.ts
  6. 33
      packages/core/src/trait_manager/model/Trait.ts

4
packages/core/src/css_composer/model/CssRule.ts

@ -7,7 +7,7 @@ import { isEmptyObj, hasWin } from '../../utils/mixins';
import Selector, { SelectorProps } from '../../selector_manager/model/Selector';
import EditorModel from '../../editor/model/Editor';
import CssRuleView from '../view/CssRuleView';
import DataVariableListenerManager from '../../data_sources/model/DataVariableListenerManager';
import DynamicVariableListenerManager from '../../data_sources/model/DataVariableListenerManager';
/** @private */
export interface CssRuleProperties {
@ -95,7 +95,7 @@ export default class CssRule extends StyleableModel<CssRuleProperties> {
em?: EditorModel;
opt: any;
views: CssRuleView[] = [];
dataVariableListeners: Record<string, DataVariableListenerManager> = {};
dynamicVariableListeners: Record<string, DynamicVariableListenerManager> = {};
defaults() {
return {

50
packages/core/src/data_sources/model/DataVariableListenerManager.ts

@ -2,47 +2,59 @@ import { DataSourcesEvents, DataVariableListener } from '../types';
import { stringToPath } from '../../utils/mixins';
import { Model } from '../../common';
import EditorModel from '../../editor/model/Editor';
import DataVariable from './DataVariable';
import DataVariable, { DataVariableType } from './DataVariable';
import ComponentView from '../../dom_components/view/ComponentView';
import ComponentDataVariable from './ComponentDataVariable';
export interface DataVariableListenerManagerOptions {
export interface DynamicVariableListenerManagerOptions {
model: Model | ComponentView;
em: EditorModel;
dataVariable: DataVariable | ComponentDataVariable;
updateValueFromDataVariable: (value: any) => void;
}
export default class DataVariableListenerManager {
export default class DynamicVariableListenerManager {
private dataListeners: DataVariableListener[] = [];
private em: EditorModel;
private model: Model | ComponentView;
private dataVariable: DataVariable | ComponentDataVariable;
private updateValueFromDataVariable: (value: any) => void;
private dynamicVariable: DataVariable | ComponentDataVariable;
private updateValueFromDynamicVariable: (value: any) => void;
constructor(options: DataVariableListenerManagerOptions) {
constructor(options: DynamicVariableListenerManagerOptions) {
this.em = options.em;
this.model = options.model;
this.dataVariable = options.dataVariable;
this.updateValueFromDataVariable = options.updateValueFromDataVariable;
this.dynamicVariable = options.dataVariable;
this.updateValueFromDynamicVariable = options.updateValueFromDataVariable;
this.listenToDataVariable();
this.listenToDynamicVariable();
}
private onChange = () => {
const value = this.dataVariable.getDataValue();
this.updateValueFromDataVariable(value);
const value = this.dynamicVariable.getDataValue();
this.updateValueFromDynamicVariable(value);
};
listenToDataVariable() {
const { em, dataVariable, model } = this;
const { path } = dataVariable.attributes;
const normPath = stringToPath(path || '').join('.');
const [ds, dr] = this.em.DataSources.fromPath(path);
listenToDynamicVariable() {
const { em, dynamicVariable, model } = this;
this.removeListeners();
const type = dynamicVariable.get('type');
let dataListeners: DataVariableListener[] = [];
switch (type) {
case DataVariableType:
dataListeners = this.listenToDataVariable(dynamicVariable, em);
break;
}
dataListeners.forEach((ls) => model.listenTo(ls.obj, ls.event, this.onChange));
this.dataListeners = dataListeners;
}
private listenToDataVariable(dataVariable: DataVariable | ComponentDataVariable, em: EditorModel) {
const dataListeners: DataVariableListener[] = [];
const { path } = dataVariable.attributes;
const normPath = stringToPath(path || '').join('.');
const [ds, dr] = this.em.DataSources.fromPath(path);
ds && dataListeners.push({ obj: ds.records, event: 'add remove reset' });
dr && dataListeners.push({ obj: dr, event: 'change' });
dataListeners.push(
@ -51,9 +63,7 @@ export default class DataVariableListenerManager {
{ obj: em, event: `${DataSourcesEvents.path}:${normPath}` },
);
dataListeners.forEach((ls) => model.listenTo(ls.obj, ls.event, this.onChange));
this.dataListeners = dataListeners;
return dataListeners;
}
private removeListeners() {

6
packages/core/src/data_sources/view/ComponentDataVariableView.ts

@ -1,13 +1,13 @@
import ComponentView from '../../dom_components/view/ComponentView';
import ComponentDataVariable from '../model/ComponentDataVariable';
import DataVariableListenerManager from '../model/DataVariableListenerManager';
import DynamicVariableListenerManager from '../model/DataVariableListenerManager';
export default class ComponentDataVariableView extends ComponentView<ComponentDataVariable> {
dataVariableListener?: DataVariableListenerManager;
dynamicVariableListener?: DynamicVariableListenerManager;
initialize(opt = {}) {
super.initialize(opt);
this.dataVariableListener = new DataVariableListenerManager({
this.dynamicVariableListener = new DynamicVariableListenerManager({
model: this,
em: this.em!,
dataVariable: this.model,

4
packages/core/src/dom_components/model/Component.ts

@ -927,8 +927,8 @@ export default class Component extends StyleableModel<ComponentProperties> {
if (name && value) attrs[name] = value;
}
if (trait.dataVariable) {
traitDataVariableAttr[name] = trait.dataVariable;
if (trait.dynamicVariable) {
traitDataVariableAttr[name] = trait.dynamicVariable;
}
});
traits.length && this.set('attributes', attrs);

24
packages/core/src/domain_abstract/model/StyleableModel.ts

@ -6,7 +6,7 @@ import { shallowDiff } from '../../utils/mixins';
import EditorModel from '../../editor/model/Editor';
import StyleDataVariable from '../../data_sources/model/StyleDataVariable';
import { DataVariableType } from '../../data_sources/model/DataVariable';
import DataVariableListenerManager from '../../data_sources/model/DataVariableListenerManager';
import DynamicVariableListenerManager from '../../data_sources/model/DataVariableListenerManager';
import CssRuleView from '../../css_composer/view/CssRuleView';
import ComponentView from '../../dom_components/view/ComponentView';
import Frame from '../../canvas/model/Frame';
@ -39,7 +39,7 @@ export const getLastStyleValue = (value: string | string[]) => {
export default class StyleableModel<T extends ObjectHash = any> extends Model<T> {
em?: EditorModel;
dataVariableListeners: Record<string, DataVariableListenerManager> = {};
dynamicVariableListeners: Record<string, DynamicVariableListenerManager> = {};
views: StyleableView[] = [];
constructor(attributes: T, options: { em?: EditorModel } = {}) {
@ -114,9 +114,17 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T>
const styleValue = newStyle[key];
if (typeof styleValue === 'object' && styleValue.type === DataVariableType) {
const styleDataVariable = new StyleDataVariable(styleValue, { em: this.em });
newStyle[key] = styleDataVariable;
this.manageDataVariableListener(styleDataVariable, key);
const dynamicType = styleValue.type;
let styleDynamicVariable;
switch (dynamicType) {
case DataVariableType:
styleDynamicVariable = new StyleDataVariable(styleValue, { em: this.em });
break;
default:
throw new Error(`Invalid data variable type. Expected '${DataVariableType}', but found '${dynamicType}'.`);
}
newStyle[key] = styleDynamicVariable;
this.manageDataVariableListener(styleDynamicVariable, key);
}
});
@ -146,10 +154,10 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T>
* Manage DataVariableListenerManager for a style property
*/
manageDataVariableListener(dataVar: StyleDataVariable, styleProp: string) {
if (this.dataVariableListeners[styleProp]) {
this.dataVariableListeners[styleProp].listenToDataVariable();
if (this.dynamicVariableListeners[styleProp]) {
this.dynamicVariableListeners[styleProp].listenToDynamicVariable();
} else {
this.dataVariableListeners[styleProp] = new DataVariableListenerManager({
this.dynamicVariableListeners[styleProp] = new DynamicVariableListenerManager({
model: this,
em: this.em!,
dataVariable: dataVar,

33
packages/core/src/trait_manager/model/Trait.ts

@ -7,10 +7,9 @@ import { isDef } from '../../utils/mixins';
import TraitsEvents, { TraitGetValueOptions, TraitOption, TraitProperties, TraitSetValueOptions } from '../types';
import TraitView from '../view/TraitView';
import Traits from './Traits';
import { DataVariableListener } from '../../data_sources/types';
import TraitDataVariable from '../../data_sources/model/TraitDataVariable';
import { DataVariableType } from '../../data_sources/model/DataVariable';
import DataVariableListenerManager from '../../data_sources/model/DataVariableListenerManager';
import DynamicVariableListenerManager from '../../data_sources/model/DataVariableListenerManager';
/**
* @property {String} id Trait id, eg. `my-trait-id`.
@ -30,9 +29,8 @@ export default class Trait extends Model<TraitProperties> {
em: EditorModel;
view?: TraitView;
el?: HTMLElement;
dataListeners: DataVariableListener[] = [];
dataVariable?: TraitDataVariable;
dataVariableListener?: DataVariableListenerManager;
dynamicVariable?: TraitDataVariable;
dynamicVariableListener?: DynamicVariableListenerManager;
defaults() {
return {
@ -59,19 +57,22 @@ export default class Trait extends Model<TraitProperties> {
}
this.em = em;
if (
this.attributes.value &&
typeof this.attributes.value === 'object' &&
this.attributes.value.type === DataVariableType
) {
this.dataVariable = new TraitDataVariable(this.attributes.value, { em: this.em, trait: this });
if (this.attributes.value && typeof this.attributes.value === 'object') {
const dataType = this.attributes.value.type;
switch (dataType) {
case DataVariableType:
this.dynamicVariable = new TraitDataVariable(this.attributes.value, { em: this.em, trait: this });
break;
default:
throw new Error(`Invalid data variable type. Expected '${DataVariableType}', but found '${dataType}'.`);
}
const dv = this.dataVariable.getDataValue();
const dv = this.dynamicVariable.getDataValue();
this.set({ value: dv });
this.dataVariableListener = new DataVariableListenerManager({
this.dynamicVariableListener = new DynamicVariableListenerManager({
model: this,
em: this.em,
dataVariable: this.dataVariable,
dataVariable: this.dynamicVariable,
updateValueFromDataVariable: this.updateValueFromDataVariable.bind(this),
});
}
@ -159,8 +160,8 @@ export default class Trait extends Model<TraitProperties> {
* @returns {any}
*/
getValue(opts?: TraitGetValueOptions) {
if (this.dataVariable) {
const dValue = this.dataVariable.getDataValue();
if (this.dynamicVariable) {
const dValue = this.dynamicVariable.getDataValue();
return dValue;
}

Loading…
Cancel
Save