diff --git a/packages/survey-creator-angular/src/adorners/item-value.component.ts b/packages/survey-creator-angular/src/adorners/item-value.component.ts index 03e47d657a..de6e733cad 100644 --- a/packages/survey-creator-angular/src/adorners/item-value.component.ts +++ b/packages/survey-creator-angular/src/adorners/item-value.component.ts @@ -37,6 +37,10 @@ export class ItemValueDesignerComponent extends CreatorModelComponent { public adorner!: PageAdorner; protected createModel(): void { if (this.model) { - this.previousModel?.dispose(); this.adorner = new PageAdorner(this.creator, this.model); } } diff --git a/packages/survey-creator-angular/src/question.component.ts b/packages/survey-creator-angular/src/question.component.ts index 49f71740bc..902676b636 100644 --- a/packages/survey-creator-angular/src/question.component.ts +++ b/packages/survey-creator-angular/src/question.component.ts @@ -47,6 +47,10 @@ export class QuestionDesignerComponent extends CreatorModelComponent { getPropertiesToTrack(): string[] { return ["creator", "row"]; } + override ngOnDestroy(): void { + super.ngOnDestroy(); + this.model.dispose(); + } + } AngularComponentFactory.Instance.registerComponent("svc-row", CreatorRowComponent); \ No newline at end of file diff --git a/packages/survey-creator-angular/src/string-editor.component.ts b/packages/survey-creator-angular/src/string-editor.component.ts index 533b15c448..3d406b310f 100644 --- a/packages/survey-creator-angular/src/string-editor.component.ts +++ b/packages/survey-creator-angular/src/string-editor.component.ts @@ -101,6 +101,9 @@ export class StringEditorComponent extends CreatorModelComponent { protected override getPropertiesToUpdateSync(): string[] { return ["mode"]; } + override ngOnDestroy(): void { + super.ngOnDestroy(); + this.model.dispose(); + } } diff --git a/packages/survey-creator-core/src/components/action-container-view-model.ts b/packages/survey-creator-core/src/components/action-container-view-model.ts index 845f48366d..7ad93da68b 100644 --- a/packages/survey-creator-core/src/components/action-container-view-model.ts +++ b/packages/survey-creator-core/src/components/action-container-view-model.ts @@ -71,6 +71,10 @@ export class SurveyElementAdornerBase e public dispose(): void { super.dispose(); this.detachElement(this.surveyElement); + this.actionContainer.dispose(); + this.creator.sidebar.onPropertyChanged.remove(this.sidebarFlyoutModeChangedFunc); + this.selectedPropPageFunc = undefined; + this.sidebarFlyoutModeChangedFunc = undefined; } protected onElementSelectedChanged(isSelected: boolean): void { if (!isSelected) return; diff --git a/packages/survey-creator-core/src/components/page-navigator/page-navigator.ts b/packages/survey-creator-core/src/components/page-navigator/page-navigator.ts index 146d97f639..d4128cb7a1 100644 --- a/packages/survey-creator-core/src/components/page-navigator/page-navigator.ts +++ b/packages/survey-creator-core/src/components/page-navigator/page-navigator.ts @@ -17,6 +17,16 @@ export class PageNavigatorViewModel extends Base { }; private _resizeObserver: ResizeObserver; + private pcPropertyChangedHandler = (sender, options) => { + if (options.name === "toolboxLocation") { + if (this.pagesController.creator["toolboxLocation"] == "sidebar") { + this.popupModel.horizontalPosition = "right"; + } else { + this.popupModel.horizontalPosition = this.pagesController.creator["toolboxLocation"]; + } + } + } + constructor(private pagesController: PagesController, private pageEditMode: string) { super(); this.icon = "icon-select-page"; @@ -38,15 +48,7 @@ export class PageNavigatorViewModel extends Base { }; this.popupModel.onHide = () => { this.isPopupOpened = false; }; if (!!this.pagesController.creator["onPropertyChanged"]) { - this.pagesController.creator["onPropertyChanged"].add((sender, options) => { - if (options.name === "toolboxLocation") { - if (this.pagesController.creator["toolboxLocation"] == "sidebar") { - this.popupModel.horizontalPosition = "right"; - } else { - this.popupModel.horizontalPosition = this.pagesController.creator["toolboxLocation"]; - } - } - }); + this.pagesController.creator["onPropertyChanged"].add(this.pcPropertyChangedHandler); } this.buildItems(); } @@ -55,6 +57,18 @@ export class PageNavigatorViewModel extends Base { this.stopItemsContainerHeightObserver(); this.pagesController.onPagesChanged.remove(this.pagesChangedFunc); this.pagesController.onCurrentPageChanged.remove(this.currentPagesChangedFunc); + if (!!this.pagesController.creator["onPropertyChanged"]) { + this.pagesController.creator["onPropertyChanged"].remove(this.pcPropertyChangedHandler); + this.pcPropertyChangedHandler = undefined; + } + if(this.pageListModel) { + this.pageListModel.dispose(); + } + if(this.popupModel) { + this.popupModel.dispose(); + } + this._scrollableContainer = undefined; + this._itemsContainer = undefined; } @propertyArray() items: Array; diff --git a/packages/survey-creator-core/src/components/page.ts b/packages/survey-creator-core/src/components/page.ts index 9ce3f929ff..9f3a32cb3d 100644 --- a/packages/survey-creator-core/src/components/page.ts +++ b/packages/survey-creator-core/src/components/page.ts @@ -15,7 +15,7 @@ export class PageAdorner extends SurveyElementAdornerBase { @property({ defaultValue: "" }) currentAddQuestionType: string; @property({ defaultValue: null }) dragTypeOverMe: DragTypeOverMeEnum; private updateDragTypeOverMe() { - this.dragTypeOverMe = this.page.dragTypeOverMe; + this.dragTypeOverMe = this.page?.dragTypeOverMe; } constructor(creator: CreatorBase, page: PageModel) { super(creator, page); @@ -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-core/src/components/question-image.ts b/packages/survey-creator-core/src/components/question-image.ts index 1376d95981..a66ffbb002 100644 --- a/packages/survey-creator-core/src/components/question-image.ts +++ b/packages/survey-creator-core/src/components/question-image.ts @@ -21,7 +21,7 @@ export class QuestionImageAdornerViewModel extends QuestionAdornerViewModel { this.filePresentationModel.storeDataAsText = false; surveyModel.onUploadFiles.add((s, o) => { const fileToUpload = o.files[0]; - if(!!fileToUpload) { + if (!!fileToUpload) { this.creator.uploadFiles(o.files, this.question, (status, link) => { this.question.imageLink = link; }); @@ -78,4 +78,9 @@ export class QuestionImageAdornerViewModel extends QuestionAdornerViewModel { public get chooseImageText(): string { return getLocString("ed.imageChooseImage"); } + + public dispose() { + super.dispose(); + this.questionRoot = undefined; + } } \ No newline at end of file diff --git a/packages/survey-creator-core/src/components/question.ts b/packages/survey-creator-core/src/components/question.ts index 023bb3b5ea..1f274c1547 100644 --- a/packages/survey-creator-core/src/components/question.ts +++ b/packages/survey-creator-core/src/components/question.ts @@ -168,6 +168,7 @@ export class QuestionAdornerViewModel extends SurveyElementAdornerBase { if (!!this.surveyElement["setCanShowOptionItemCallback"]) { (this.surveyElement).setCanShowOptionItemCallback(undefined); } + super.dispose(); } get isDraggable() { return true; diff --git a/packages/survey-creator-core/src/components/side-bar/side-bar-model.ts b/packages/survey-creator-core/src/components/side-bar/side-bar-model.ts index c51397deff..35ad3a4108 100644 --- a/packages/survey-creator-core/src/components/side-bar/side-bar-model.ts +++ b/packages/survey-creator-core/src/components/side-bar/side-bar-model.ts @@ -91,6 +91,11 @@ export class SidebarModel extends Base { private getCurrentHandles(): string { return this.creator.sidebarLocation == "right" ? "w" : "e"; } + private sidebarLocationChangedHandler = (sender, options) => { + if (options.name === "sidebarLocation" && !!this.resizeManager) { + this.resizeManager.setHandles(this.getCurrentHandles()); + } + }; constructor(private creator: CreatorBase) { super(); @@ -99,11 +104,7 @@ export class SidebarModel extends Base { this.visible = options.show; }; this.creator.onShowSidebarVisibilityChanged.add(this.onSidebarVisibilityChanged); - this.creator.onPropertyChanged.add((sender, options) => { - if (options.name === "sidebarLocation" && !!this.resizeManager) { - this.resizeManager.setHandles(this.getCurrentHandles()); - } - }); + this.creator.onPropertyChanged.add(this.sidebarLocationChangedHandler); this.visible = this.creator.showSidebar; this.createActions(); } @@ -131,7 +132,10 @@ export class SidebarModel extends Base { public dispose() { if (!!this.creator && !this.isDisposed) { this.creator.onShowSidebarVisibilityChanged.remove(this.onSidebarVisibilityChanged); + this.creator.onPropertyChanged.remove(this.sidebarLocationChangedHandler); + this.sidebarLocationChangedHandler = undefined; } + this.resetResizeManager(); super.dispose(); } public initResizeManager(container: HTMLDivElement): void { diff --git a/packages/survey-creator-core/src/components/string-editor.ts b/packages/survey-creator-core/src/components/string-editor.ts index cb72c43051..bec7098c6c 100644 --- a/packages/survey-creator-core/src/components/string-editor.ts +++ b/packages/survey-creator-core/src/components/string-editor.ts @@ -25,7 +25,7 @@ export abstract class StringItemsNavigatorBase { protected addNewItems(items: any, startIndex: number, itemsToAdd: string[]) { const createNewItem = (val: any): ItemValue => { - if(this.question.createItemValue) return this.question.createItemValue(val); + if (this.question.createItemValue) return this.question.createItemValue(val); return new ItemValue(val); }; let newItems = items.slice(0, startIndex).concat(itemsToAdd.map(text => createNewItem(text))).concat(items.slice(startIndex + 1)); @@ -117,7 +117,7 @@ class StringItemsNavigatorSelectBase extends StringItemsNavigatorBase { } protected addNewItem(creator: CreatorBase, items: any, text: string = null) { const itemValue = creator.createNewItemValue(this.question); - if(!!text) itemValue.value = text; + if (!!text) itemValue.value = text; } protected getItemsPropertyName(items: any) { return "choices"; @@ -217,9 +217,7 @@ export class StringEditorViewModelBase extends Base { constructor(private locString: LocalizableString, private creator: CreatorBase) { super(); - this.connector = StringEditorConnector.get(locString); - this.connector.onDoActivate.add(() => { this.activate(); }); - this.checkMarkdownToTextConversion(this.locString.owner, this.locString.name); + this.setLocString(locString); } public afterRender() { @@ -228,7 +226,12 @@ export class StringEditorViewModelBase extends Base { } } - public activate() { + public dispose() { + super.dispose(); + this.connector.onDoActivate.remove(this.activate); + } + + public activate = () => { const element = this.getEditorElement(); if (element && element.offsetParent != null) { element.focus(); @@ -239,9 +242,11 @@ export class StringEditorViewModelBase extends Base { } public setLocString(locString: LocalizableString) { + this.connector?.onDoActivate.clear(); this.locString = locString; this.connector = StringEditorConnector.get(locString); - this.connector.onDoActivate.add(() => { this.activate(); }); + this.connector.onDoActivate.add(this.activate); + this.checkMarkdownToTextConversion(this.locString.owner, this.locString.name); } public checkConstraints(event: any) { if (this.maxLength > 0 && event.keyCode >= 32) { @@ -373,12 +378,12 @@ export class StringEditorViewModelBase extends Base { this.creator.inplaceEditForValues && ["noneText", "otherText", "selectAllText"].indexOf(this.locString.name) == -1) { const itemValue = this.locString.owner; - if(itemValue.value !== clearedText) { - if(!!itemValue.locOwner && !!itemValue.ownerPropertyName) { + if (itemValue.value !== clearedText) { + if (!!itemValue.locOwner && !!itemValue.ownerPropertyName) { const choices = itemValue.locOwner[itemValue.ownerPropertyName]; - if(Array.isArray(choices) && !!ItemValue.getItemByValue(choices, clearedText)) { + if (Array.isArray(choices) && !!ItemValue.getItemByValue(choices, clearedText)) { clearedText = getNextItemValue(clearedText, choices); - if(!!event && !!event.target) { + if (!!event && !!event.target) { event.target.innerText = clearedText; } } diff --git a/packages/survey-creator-core/src/components/tabs/designer-plugin.ts b/packages/survey-creator-core/src/components/tabs/designer-plugin.ts index 88fce2cdc6..879dfc6856 100644 --- a/packages/survey-creator-core/src/components/tabs/designer-plugin.ts +++ b/packages/survey-creator-core/src/components/tabs/designer-plugin.ts @@ -125,12 +125,8 @@ export class TabDesignerPlugin implements ICreatorPlugin { action: () => { this.selectSurvey(); }, - active: new ComputedUpdater(() => { - return notShortCircuitAnd(this.creator.sidebar.activeTab === this.propertyGridTab.id, this.isSurveySelected); - }), - pressed: new ComputedUpdater(() => { - return notShortCircuitAnd(this.creator.sidebar.activeTab === this.propertyGridTab.id, this.isSurveySelected); - }), + active: this.isSettingsActive, + pressed: this.isSettingsActive, visible: this.createVisibleUpdater(), locTitleName: "ed.surveySettings", locTooltipName: "ed.surveySettingsTooltip", diff --git a/packages/survey-creator-core/src/components/tabs/test-plugin.ts b/packages/survey-creator-core/src/components/tabs/test-plugin.ts index bb7cc926f9..74768d9ecf 100644 --- a/packages/survey-creator-core/src/components/tabs/test-plugin.ts +++ b/packages/survey-creator-core/src/components/tabs/test-plugin.ts @@ -111,6 +111,7 @@ export class TabTestPlugin implements ICreatorPlugin { if (this.model) { this.simulatorTheme = this.model.simulator.survey.css; this.model.onSurveyCreatedCallback = undefined; + this.model.dispose(); this.model = undefined; } this.languageSelectorAction.visible = false; diff --git a/packages/survey-creator-core/src/components/tabs/test.ts b/packages/survey-creator-core/src/components/tabs/test.ts index 71e9305e9b..5da9a64c3d 100644 --- a/packages/survey-creator-core/src/components/tabs/test.ts +++ b/packages/survey-creator-core/src/components/tabs/test.ts @@ -307,4 +307,10 @@ export class TestSurveyTabViewModel extends Base { this.survey.onScroll(); return true; } + public dispose(): void { + if (this.selectPageAction) { + this.selectPageAction.dispose(); + } + this.simulator.dispose(); + } } diff --git a/packages/survey-creator-core/src/components/tabs/theme-plugin.ts b/packages/survey-creator-core/src/components/tabs/theme-plugin.ts index 5459143cb8..d3c2ef1b83 100644 --- a/packages/survey-creator-core/src/components/tabs/theme-plugin.ts +++ b/packages/survey-creator-core/src/components/tabs/theme-plugin.ts @@ -90,6 +90,7 @@ export class TabThemePlugin implements ICreatorPlugin { if (this.model) { this.simulatorTheme = this.model.simulator.survey.css; this.model.onSurveyCreatedCallback = undefined; + this.model.dispose(); this.model = undefined; } this.sidebarTab.visible = false; diff --git a/packages/survey-creator-core/src/components/tabs/theme.ts b/packages/survey-creator-core/src/components/tabs/theme.ts index fb606300e6..a1d7c6fff1 100644 --- a/packages/survey-creator-core/src/components/tabs/theme.ts +++ b/packages/survey-creator-core/src/components/tabs/theme.ts @@ -1077,4 +1077,11 @@ export class ThemeSurveyTabViewModel extends Base { return themeEditorSurveyJSON; } + public dispose(): void { + this.themeEditorSurveyValue?.dispose(); + if (this.selectPageAction) { + this.selectPageAction.dispose(); + } + this.simulator.dispose(); + } } diff --git a/packages/survey-creator-knockout/src/adorners/question.ts b/packages/survey-creator-knockout/src/adorners/question.ts index 3d77e56fa7..2009aa5812 100644 --- a/packages/survey-creator-knockout/src/adorners/question.ts +++ b/packages/survey-creator-knockout/src/adorners/question.ts @@ -27,9 +27,9 @@ export function createQuestionViewModel( return model.isEmptyElement; }); model["adornerComponent"] = undefined; - new ImplementorBase(model); + const implementor = new ImplementorBase(model); ko.utils.domNodeDisposal.addDisposeCallback(componentInfo.element, () => { - model.dispose(); + implementor.dispose(); }); return model; } diff --git a/packages/survey-creator-knockout/src/page-navigator/page-navigator.ts b/packages/survey-creator-knockout/src/page-navigator/page-navigator.ts index a7d744f041..8932f5e1ba 100644 --- a/packages/survey-creator-knockout/src/page-navigator/page-navigator.ts +++ b/packages/survey-creator-knockout/src/page-navigator/page-navigator.ts @@ -27,7 +27,7 @@ ko.components.register("svc-page-navigator", { createViewModel: (params: any, componentInfo: any) => { const model = new PageNavigatorView(params.controller, params.pageEditMode); model.setItemsContainer(componentInfo.element.parentElement); - new ImplementorBase(model); + const implementor = new ImplementorBase(model); const scrollableViewPort = componentInfo.element.parentElement.parentElement.parentElement; model.setScrollableContainer(scrollableViewPort); if (params.pageEditMode !== "bypage") { @@ -38,6 +38,7 @@ ko.components.register("svc-page-navigator", { ko.utils.domNodeDisposal.addDisposeCallback(componentInfo.element, () => { scrollableViewPort.onscroll = undefined; model.dispose(); + implementor.dispose(); }); return model; }, diff --git a/packages/survey-creator-knockout/src/page.ts b/packages/survey-creator-knockout/src/page.ts index 6c37ec6ae1..d932f65ca6 100644 --- a/packages/survey-creator-knockout/src/page.ts +++ b/packages/survey-creator-knockout/src/page.ts @@ -33,6 +33,10 @@ export class CreatorSurveyPageComponent extends PageAdorner { fixedDispose(): void { this.pageUpdater && this.pageUpdater.dispose(); super.dispose(); + if(ko.isWritableObservable(this._page)) { + (this._page as ko.Observable)(undefined); + } + this._page = undefined; } dispose(): void { diff --git a/packages/survey-creator-knockout/src/string-editor.ts b/packages/survey-creator-knockout/src/string-editor.ts index 7f72baaf6a..cf7d488d30 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,14 @@ 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(); } } @@ -180,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-knockout/src/tabbed-menu/tabbed-menu.ts b/packages/survey-creator-knockout/src/tabbed-menu/tabbed-menu.ts index d7f7d22eee..f64e991cd7 100644 --- a/packages/survey-creator-knockout/src/tabbed-menu/tabbed-menu.ts +++ b/packages/survey-creator-knockout/src/tabbed-menu/tabbed-menu.ts @@ -12,16 +12,17 @@ ko.components.register("svc-tabbed-menu", { createViewModel: (params: any, componentInfo: any) => { const model = params.model; const container: HTMLDivElement = componentInfo.element.nextElementSibling; - new ActionContainerImplementor(model); + const reactivityImplementor = new ActionContainerImplementor(model); const manager: ResponsivityManager = new ResponsivityManager( container, model, ".svc-tabbed-menu-item-container:not(.sv-dots)>.sv-action__content" ); - ko.utils.domNodeDisposal.addDisposeCallback(container, () => - manager.dispose() - ); + ko.utils.domNodeDisposal.addDisposeCallback(container, () => { + manager.dispose(); + reactivityImplementor.dispose(); + }); return model; } }, diff --git a/packages/survey-creator-react/src/StringEditor.tsx b/packages/survey-creator-react/src/StringEditor.tsx index f48cee6dce..0e21bfbdd3 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"]) { @@ -56,10 +58,14 @@ export class SurveyLocStringEditor extends CreatorModelElement { } public componentDidUpdate(prevProps: any, prevState: any): void { super.componentDidUpdate(prevProps, prevState); + this.baseModel.setLocString(this.locString); this.baseModel.afterRender(); } public componentWillUnmount() { super.componentWillUnmount(); + this.baseModel.getEditorElement = undefined; + this.baseModel.blurEditor = undefined; + this.baseModel.dispose(); if (!this.locString) return; this.locString.onStringChanged.remove(this.onChangedHandler); } @@ -119,9 +125,6 @@ export class SurveyLocStringEditor extends CreatorModelElement { if (!this.locString) { return null; } - else { - this.baseModel.setLocString(this.locString); - } let control = null; if (this.locString.hasHtml) { const htmlValue = { __html: this.baseModel.focused && this.baseModel.editAsText && this.locString.text || this.locString.renderedHtml }; diff --git a/packages/survey-creator-react/src/adorners/Page.tsx b/packages/survey-creator-react/src/adorners/Page.tsx index 60a0333247..61bc755e4c 100644 --- a/packages/survey-creator-react/src/adorners/Page.tsx +++ b/packages/survey-creator-react/src/adorners/Page.tsx @@ -56,6 +56,7 @@ export class CreatorSurveyPageComponent extends CreatorModelElement< } componentWillUnmount() { super.componentWillUnmount(); + this.model.onPageSelectedCallback = undefined; this.model.dispose(); } protected canRender(): boolean { 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 {