diff --git a/packages/survey-creator-core/src/components/page.ts b/packages/survey-creator-core/src/components/page.ts index 9ce3f929ff..13a0dc9a18 100644 --- a/packages/survey-creator-core/src/components/page.ts +++ b/packages/survey-creator-core/src/components/page.ts @@ -93,8 +93,8 @@ export class PageAdorner extends SurveyElementAdornerBase { }; } public dispose(): void { - super.dispose(); this.detachElement(this.page); + super.dispose(); this.onPropertyValueChangedCallback = undefined; } public get isGhost(): boolean { diff --git a/packages/survey-creator-knockout/src/adorners/question.ts b/packages/survey-creator-knockout/src/adorners/question.ts index d2c182faa2..2009aa5812 100644 --- a/packages/survey-creator-knockout/src/adorners/question.ts +++ b/packages/survey-creator-knockout/src/adorners/question.ts @@ -30,7 +30,6 @@ export function createQuestionViewModel( const implementor = new ImplementorBase(model); ko.utils.domNodeDisposal.addDisposeCallback(componentInfo.element, () => { implementor.dispose(); - model.dispose(); }); return model; } diff --git a/packages/survey-creator-knockout/src/string-editor.ts b/packages/survey-creator-knockout/src/string-editor.ts index c2534ed83c..ad053101d2 100644 --- a/packages/survey-creator-knockout/src/string-editor.ts +++ b/packages/survey-creator-knockout/src/string-editor.ts @@ -4,25 +4,23 @@ import { LocalizableString } from "survey-core"; import { ImplementorBase } from "survey-knockout-ui"; const template = require("./string-editor.html"); +function getEditorElement(element: HTMLElement) { + return (element.nextSibling as any).getElementsByClassName("sv-string-editor")[0]; +}; + export class StringEditorViewModel { private implementor = undefined; private baseModel: StringEditorViewModelBase; - getEditorElement = (element) => { - return element.nextSibling.getElementsByClassName( - "sv-string-editor" - )[0]; - }; - constructor(public locString: any, private creator: CreatorBase, element: any) { this.baseModel = new StringEditorViewModelBase(locString, creator); - this.baseModel.getEditorElement = () => this.getEditorElement(element); + this.baseModel.getEditorElement = () => getEditorElement(element); this.implementor = new ImplementorBase(this.baseModel); this.focusEditor = () => { - this.getEditorElement(element).focus(); + getEditorElement(element).focus(); }; this.baseModel.blurEditor = () => { - const editorElement = this.getEditorElement(element); + const editorElement = getEditorElement(element); editorElement.blur(); editorElement.spellcheck = false; }; @@ -34,7 +32,7 @@ export class StringEditorViewModel { return locString; } - public afterRender = ()=>{ + public afterRender = () => { this.baseModel.afterRender(); } @@ -52,7 +50,7 @@ export class StringEditorViewModel { return this.baseModel.placeholder; } public get contentEditable(): string { - return this.baseModel.contentEditable?"true":"false"; + return this.baseModel.contentEditable ? "true" : "false"; } public get characterCounter(): any { return this.baseModel.characterCounter; @@ -116,10 +114,12 @@ export class StringEditorViewModel { public focusEditor: () => void; public dispose(): void { this.locString.onSearchChanged = undefined; + if (!!this.implementor) { + this.implementor.dispose(); + this.implementor = undefined; + } this.focusEditor = undefined; this.baseModel.blurEditor = undefined; - this.implementor.dispose(); - this.implementor = undefined; this.baseModel.getEditorElement = undefined; this.baseModel.dispose(); } @@ -182,6 +182,7 @@ ko.components.register(editableStringRendererName, { ko.utils.domNodeDisposal.addDisposeCallback(componentInfo.element, () => { subscrib.dispose(); + model.dispose(); }); return model; }, diff --git a/packages/survey-creator-react/src/StringEditor.tsx b/packages/survey-creator-react/src/StringEditor.tsx index f48cee6dce..92f355e125 100644 --- a/packages/survey-creator-react/src/StringEditor.tsx +++ b/packages/survey-creator-react/src/StringEditor.tsx @@ -11,14 +11,12 @@ export class SurveyLocStringEditor extends CreatorModelElement { super(props); this.state = { changed: 0 }; this.svStringEditorRef = React.createRef(); - this.baseModel.getEditorElement = () => this.svStringEditorRef.current; } protected createModel(): void { + if (this.baseModel) { + this.baseModel.dispose(); + } this.baseModel = new StringEditorViewModelBase(this.locString, this.creator); - this.baseModel.blurEditor = () => { - this.svStringEditorRef.current.blur(); - this.svStringEditorRef.current.spellcheck = false; - }; } protected getUpdatedModelProps(): string[] { return ["creator", "locString"]; @@ -46,7 +44,11 @@ export class SurveyLocStringEditor extends CreatorModelElement { public componentDidMount() { super.componentDidMount(); if (!this.locString) return; - const self: SurveyLocStringEditor = this; + this.baseModel.getEditorElement = () => this.svStringEditorRef.current; + this.baseModel.blurEditor = () => { + this.svStringEditorRef.current.blur(); + this.svStringEditorRef.current.spellcheck = false; + }; this.baseModel.afterRender(); this.locString.onStringChanged.add(this.onChangedHandler); if (this.locString["__isEditing"]) { @@ -60,6 +62,8 @@ export class SurveyLocStringEditor extends CreatorModelElement { } public componentWillUnmount() { super.componentWillUnmount(); + this.baseModel.getEditorElement = undefined; + this.baseModel.blurEditor = undefined; if (!this.locString) return; this.locString.onStringChanged.remove(this.onChangedHandler); } diff --git a/packages/survey-creator-react/src/adorners/Question.tsx b/packages/survey-creator-react/src/adorners/Question.tsx index 35c0c98f5d..cc8b8dfec3 100644 --- a/packages/survey-creator-react/src/adorners/Question.tsx +++ b/packages/survey-creator-react/src/adorners/Question.tsx @@ -26,6 +26,9 @@ export class QuestionAdornerComponent extends CreatorModelElement< protected rootRef: React.RefObject; protected createModel(): void { + if (this.modelValue) { + this.modelValue.dispose(); + } this.modelValue = this.createQuestionViewModel(); } protected createQuestionViewModel(): QuestionAdornerViewModel {