Browse Source

Refactor component dynamic values

pull/6351/head
mohamedsalem401 1 year ago
parent
commit
bbbeee4fe9
  1. 42
      packages/core/src/dom_components/model/Component.ts
  2. 26
      packages/core/src/dom_components/model/ComponentDynamicValueWatcher.ts
  3. 30
      packages/core/src/dom_components/model/DynamicValueWatcher.ts

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

@ -51,15 +51,16 @@ import {
updateSymbolComps,
updateSymbolProps,
} from './SymbolUtils';
import { ComponentDynamicValueWatcher } from './ComponentDynamicValueListener';
import { ComponentDynamicValueWatcher } from './ComponentDynamicValueWatcher';
import { DynamicValueWatcher } from './DynamicValueWatcher';
export interface IComponent extends ExtractMethods<Component> { }
export interface IComponent extends ExtractMethods<Component> {}
export interface DynamicWatchersOptions {
skipWatcherUpdates?: boolean;
fromDataSource?: boolean;
}
export interface SetAttrOptions extends SetOptions, UpdateStyleOptions, DynamicWatchersOptions { }
export interface ComponentSetOptions extends SetOptions, DynamicWatchersOptions { }
export interface SetAttrOptions extends SetOptions, UpdateStyleOptions, DynamicWatchersOptions {}
export interface ComponentSetOptions extends SetOptions, DynamicWatchersOptions {}
const escapeRegExp = (str: string) => {
return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
@ -226,12 +227,12 @@ export default class Component extends StyleableModel<ComponentProperties> {
return this.frame?.getPage();
}
preInit() { }
preInit() {}
/**
* Hook method, called once the model is created
*/
init() { }
init() {}
/**
* Hook method, called when the model has been updated (eg. updated some model's property)
@ -239,12 +240,12 @@ export default class Component extends StyleableModel<ComponentProperties> {
* @param {*} value Property value, if triggered after some property update
* @param {*} previous Property previous value, if triggered after some property update
*/
updated(property: string, value: any, previous: any) { }
updated(property: string, value: any, previous: any) {}
/**
* Hook method, called once the model has been removed
*/
removed() { }
removed() {}
em!: EditorModel;
opt!: ComponentOptions;
@ -264,8 +265,7 @@ export default class Component extends StyleableModel<ComponentProperties> {
componentDVListener: ComponentDynamicValueWatcher;
constructor(props: ComponentProperties = {}, opt: ComponentOptions) {
const evaluatedProps = ComponentDynamicValueWatcher.evaluateComponentDef(props, opt.em);
super(evaluatedProps, opt);
super(props, opt);
this.componentDVListener = new ComponentDynamicValueWatcher(this, opt.em);
this.componentDVListener.watchComponentDef(props);
@ -295,7 +295,7 @@ export default class Component extends StyleableModel<ComponentProperties> {
this.opt = opt;
this.em = em!;
this.config = opt.config || {};
this.set('attributes', {
this.setAttributes({
...(result(this, 'defaults').attributes || {}),
...(this.get('attributes') || {}),
});
@ -343,7 +343,7 @@ export default class Component extends StyleableModel<ComponentProperties> {
optionsOrUndefined?: ComponentSetOptions,
): this {
let attributes: Partial<ComponentProperties>;
let options: ComponentSetOptions = { skipWatcherUpdates: false };
let options: ComponentSetOptions = { skipWatcherUpdates: false, fromDataSource: false };
if (typeof keyOrAttributes === 'object') {
attributes = keyOrAttributes;
options = valueOrOptions || (options as ComponentSetOptions);
@ -360,11 +360,14 @@ export default class Component extends StyleableModel<ComponentProperties> {
if (areStaticAttributes) {
evaluatedAttributes = attributes;
} else {
evaluatedAttributes = ComponentDynamicValueWatcher.evaluateComponentDef(attributes, this.em);
// @ts-ignore
const em = this.em || options.em;
evaluatedAttributes = ComponentDynamicValueWatcher.evaluateComponentDef(attributes, em);
}
if (!options.skipWatcherUpdates) {
this.componentDVListener?.watchProps(attributes);
const shouldSkipWatcherUpdates = options.skipWatcherUpdates || options.fromDataSource;
if (!shouldSkipWatcherUpdates) {
this.componentDVListener?.addProps(attributes);
}
return super.set(evaluatedAttributes, options);
@ -687,9 +690,12 @@ export default class Component extends StyleableModel<ComponentProperties> {
* @example
* component.setAttributes({ id: 'test', 'data-key': 'value' });
*/
setAttributes(attrs: ObjectAny, opts: SetAttrOptions = { skipWatcherUpdates: false }) {
const evaluatedAttributes = DynamicValueWatcher.getStaticValues(attrs, this.em);
if (!opts.skipWatcherUpdates) {
setAttributes(attrs: ObjectAny, opts: SetAttrOptions = { skipWatcherUpdates: false, fromDataSource: false }) {
// @ts-ignore
const em = this.em || opts.em;
const evaluatedAttributes = DynamicValueWatcher.getStaticValues(attrs, em);
const shouldSkipWatcherUpdates = opts.skipWatcherUpdates || opts.fromDataSource;
if (!shouldSkipWatcherUpdates) {
this.componentDVListener.setAttributes(attrs);
}
this.set('attributes', { ...evaluatedAttributes }, opts);

26
packages/core/src/dom_components/model/ComponentDynamicValueWatcher.ts

@ -19,13 +19,13 @@ export class ComponentDynamicValueWatcher {
private createPropertyUpdater() {
return (key: string, value: any) => {
this.component.set(key, value, { skipWatcherUpdates: false, avoidStore: true });
this.component.set(key, value, { skipWatcherUpdates: true, avoidStore: true });
};
}
private createAttributeUpdater() {
return (key: string, value: any) => {
this.component.addAttributes({ [key]: value }, { skipWatcherUpdates: false });
this.component.addAttributes({ [key]: value }, { skipWatcherUpdates: true, avoidStore: true });
};
}
@ -64,14 +64,13 @@ export class ComponentDynamicValueWatcher {
}
watchComponentDef(values: ObjectAny) {
this.watchProps(values);
this.watchAttributes(values.attributes);
this.watchTraits(values.traits);
this.addProps(values);
this.addAttributes(values.attributes);
this.addTraits(values.traits);
}
watchProps(props: ObjectAny) {
this.propertyWatcher.removeListeners(Object.keys(props));
this.propertyWatcher.watchDynamicValue(props);
addProps(props: ObjectAny) {
this.propertyWatcher.addDynamicValues(props);
}
getDynamicPropsDefs() {
@ -79,15 +78,14 @@ export class ComponentDynamicValueWatcher {
}
setAttributes(attributes: ObjectAny) {
this.attributeWatcher.removeListeners();
this.attributeWatcher.watchDynamicValue(attributes);
this.attributeWatcher.setDynamicValues(attributes);
}
watchAttributes(attributes: ObjectAny) {
this.attributeWatcher.watchDynamicValue(attributes);
addAttributes(attributes: ObjectAny) {
this.attributeWatcher.addDynamicValues(attributes);
}
watchTraits(traits: (string | ObjectAny)[]) {
addTraits(traits: (string | ObjectAny)[]) {
const evaluatedTraits: { [key: string]: ObjectAny } = {};
traits?.forEach((trait: any) => {
@ -96,7 +94,7 @@ export class ComponentDynamicValueWatcher {
}
});
this.traitsWatcher.watchDynamicValue(evaluatedTraits);
this.traitsWatcher.addDynamicValues(evaluatedTraits);
}
removeAttributes(attributes: string[]) {

30
packages/core/src/dom_components/model/DynamicValueWatcher.ts

@ -1,6 +1,7 @@
import { ObjectAny } from '../../common';
import DynamicVariableListenerManager from '../../data_sources/model/DataVariableListenerManager';
import { evaluateDynamicValueDefinition, isDynamicValueDefinition } from '../../data_sources/model/utils';
import { DynamicValue } from '../../data_sources/types';
import EditorModel from '../../editor/model/Editor';
export class DynamicValueWatcher {
@ -10,7 +11,8 @@ export class DynamicValueWatcher {
private em: EditorModel,
) {}
static getStaticValues(values: ObjectAny, em: EditorModel): ObjectAny {
static getStaticValues(values: ObjectAny | undefined, em: EditorModel): ObjectAny {
if (!values) return {};
const evaluatedValues: ObjectAny = { ...values };
const propsKeys = Object.keys(values);
@ -25,13 +27,21 @@ export class DynamicValueWatcher {
return evaluatedValues;
}
static areStaticValues(values: ObjectAny) {
static areStaticValues(values: ObjectAny | undefined) {
if (!values) return true;
return Object.keys(values).every((key) => {
return !isDynamicValueDefinition(values[key]);
});
}
watchDynamicValue(values: ObjectAny) {
setDynamicValues(values: ObjectAny | undefined) {
this.removeListeners();
return this.addDynamicValues(values);
}
addDynamicValues(values: ObjectAny | undefined) {
if (!values) return {};
this.removeListeners(Object.keys(values));
const dynamicProps = this.getDynamicValues(values);
const propsKeys = Object.keys(dynamicProps);
for (let index = 0; index < propsKeys.length; index++) {
@ -50,15 +60,16 @@ export class DynamicValueWatcher {
}
private getDynamicValues(values: ObjectAny) {
const dynamicValues = { ...values };
const propsKeys = Object.keys(dynamicValues);
const dynamicValues: {
[key: string]: DynamicValue;
} = {};
const propsKeys = Object.keys(values);
for (let index = 0; index < propsKeys.length; index++) {
const key = propsKeys[index];
if (!isDynamicValueDefinition(dynamicValues[key])) {
delete dynamicValues[key];
if (!isDynamicValueDefinition(values[key])) {
continue;
}
const { variable } = evaluateDynamicValueDefinition(dynamicValues[key], this.em);
const { variable } = evaluateDynamicValueDefinition(values[key], this.em);
dynamicValues[key] = variable;
}
@ -80,7 +91,8 @@ export class DynamicValueWatcher {
});
}
getSerializableValues(values: ObjectAny) {
getSerializableValues(values: ObjectAny | undefined) {
if (!values) return {};
const serializableValues = { ...values };
const propsKeys = Object.keys(serializableValues);
for (let index = 0; index < propsKeys.length; index++) {

Loading…
Cancel
Save