From 332635ef6172d328838ca2ceddadee52f4a67cb3 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Sat, 16 Dec 2023 12:08:26 +0400 Subject: [PATCH] Avoid getValue with traits having getValue property --- src/trait_manager/model/Trait.ts | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/trait_manager/model/Trait.ts b/src/trait_manager/model/Trait.ts index df11b03e2..de945ffba 100644 --- a/src/trait_manager/model/Trait.ts +++ b/src/trait_manager/model/Trait.ts @@ -59,10 +59,16 @@ export interface TraitProperties { trait: Trait; component: Component; partial: boolean; + options: TraitSetValueOptions; emitUpdate: () => void; }) => void; } +interface TraitSetValueOptions { + partial?: boolean; + [key: string]: unknown; +} + type TraitOption = { id: string; label?: string; @@ -110,12 +116,15 @@ export default class Trait extends Model { setTarget(target: Component) { if (target) { - const { name, changeProp, value: initValue } = this.attributes; + const { name, changeProp, value: initValue, getValue } = this.attributes; this.target = target; this.unset('target'); const targetEvent = changeProp ? `change:${name}` : `change:attributes:${name}`; this.listenTo(target, targetEvent, this.targetUpdated); - const value = initValue || this.getValue(); + const value = + initValue || + // Avoid the risk of loops in case the trait has a custom getValue + (!getValue ? this.getValue() : undefined); !isUndefined(value) && this.set({ value }, { silent: true }); } } @@ -173,7 +182,7 @@ export default class Trait extends Model { * @param {Object} [opts={}] Options. * @param {Boolean} [opts.partial] If `true` the update won't be considered complete (not stored in UndoManager). */ - setValue(value: any, opts: { partial?: boolean } = {}) { + setValue(value: any, opts: TraitSetValueOptions = {}) { const valueOpts: { avoidStore?: boolean } = {}; const setValue = this.get('setValue'); @@ -184,6 +193,7 @@ export default class Trait extends Model { trait: this, component: this.target, partial: !!opts.partial, + options: opts, emitUpdate: () => this.targetUpdated(), }); return;