Skip to content

Commit 6497a15

Browse files
Destroy dynamically generated components in onDestroy & replace deprecated createComponent
1 parent b28e24f commit 6497a15

5 files changed

Lines changed: 78 additions & 54 deletions

File tree

src/app/admin/admin-search-page/admin-search-results/admin-search-result-grid-element/item-search-result/item-admin-search-result-grid-element.component.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ export class ItemAdminSearchResultGridElementComponent extends SearchResultGridE
6161
],
6262
},
6363
);
64-
(this.compRef.instance as any).object = this.object;
65-
(this.compRef.instance as any).index = this.index;
66-
(this.compRef.instance as any).linkType = this.linkType;
67-
(this.compRef.instance as any).listID = this.listID;
64+
this.compRef.setInput('object',this.object);
65+
this.compRef.setInput('index', this.index);
66+
this.compRef.setInput('linkType', this.linkType);
67+
this.compRef.setInput('listID', this.listID);
6868
}
6969

7070
ngOnDestroy(): void {

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workflow-item/workflow-item-search-result-admin-workflow-grid-element.component.ts

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -77,28 +77,27 @@ export class WorkflowItemSearchResultAdminWorkflowGridElementComponent extends S
7777
this.dso = this.linkService.resolveLink(this.dso, followLink('item'));
7878
this.item$ = (this.dso.item as Observable<RemoteData<Item>>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload());
7979
this.item$.pipe(take(1)).subscribe((item: Item) => {
80-
const component: GenericConstructor<Component> = this.getComponent(item);
80+
const component: GenericConstructor<Component> = this.getComponent(item);
8181

82-
const viewContainerRef = this.listableObjectDirective.viewContainerRef;
83-
viewContainerRef.clear();
82+
const viewContainerRef = this.listableObjectDirective.viewContainerRef;
83+
viewContainerRef.clear();
8484

85-
this.compRef = viewContainerRef.createComponent(
86-
component, {
87-
index: 0,
88-
injector: undefined,
89-
projectableNodes: [
90-
[this.badges.nativeElement],
91-
[this.buttons.nativeElement],
92-
],
93-
},
94-
);
95-
(this.compRef.instance as any).object = item;
96-
(this.compRef.instance as any).index = this.index;
97-
(this.compRef.instance as any).linkType = this.linkType;
98-
(this.compRef.instance as any).listID = this.listID;
85+
this.compRef = viewContainerRef.createComponent(
86+
component, {
87+
index: 0,
88+
injector: undefined,
89+
projectableNodes: [
90+
[this.badges.nativeElement],
91+
[this.buttons.nativeElement],
92+
],
93+
},
94+
);
95+
this.compRef.setInput('object', item);
96+
this.compRef.setInput('index', this.index);
97+
this.compRef.setInput('linkType', this.linkType);
98+
this.compRef.setInput('listID', this.listID);
9999
this.compRef.changeDetectorRef.detectChanges();
100-
}
101-
);
100+
});
102101
}
103102

104103
ngOnDestroy(): void {

src/app/admin/admin-workflow-page/admin-workflow-search-results/admin-workflow-search-result-grid-element/workspace-item/workspace-item-search-result-admin-workflow-grid-element.component.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, ComponentFactoryResolver, ElementRef, ViewChild, OnInit } from '@angular/core';
1+
import { Component, ElementRef, ViewChild, OnInit, OnDestroy, ComponentRef } from '@angular/core';
22

33
import { BehaviorSubject, Observable } from 'rxjs';
44
import { map, mergeMap, take, tap } from 'rxjs/operators';
@@ -37,6 +37,7 @@ import { SupervisionOrder } from '../../../../../core/supervision-order/models/s
3737
import { PaginatedList } from '../../../../../core/data/paginated-list.model';
3838
import { SupervisionOrderDataService } from '../../../../../core/supervision-order/supervision-order-data.service';
3939
import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service';
40+
import { hasValue } from '../../../../../shared/empty.util';
4041

4142
@listableObjectComponent(WorkspaceItemSearchResult, ViewMode.GridElement, Context.AdminWorkflowSearch)
4243
@Component({
@@ -47,7 +48,7 @@ import { DSONameService } from '../../../../../core/breadcrumbs/dso-name.service
4748
/**
4849
* The component for displaying a grid element for an workflow item on the admin workflow search page
4950
*/
50-
export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends SearchResultGridElementComponent<WorkspaceItemSearchResult, WorkspaceItem> implements OnInit {
51+
export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends SearchResultGridElementComponent<WorkspaceItemSearchResult, WorkspaceItem> implements OnDestroy, OnInit {
5152

5253
/**
5354
* The item linked to the workspace item
@@ -79,9 +80,13 @@ export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends
7980
*/
8081
@ViewChild('buttons', { static: true }) buttons: ElementRef;
8182

83+
/**
84+
* The reference to the dynamic component
85+
*/
86+
protected compRef: ComponentRef<Component>;
87+
8288
constructor(
8389
public dsoNameService: DSONameService,
84-
private componentFactoryResolver: ComponentFactoryResolver,
8590
private linkService: LinkService,
8691
protected truncatableService: TruncatableService,
8792
private themeService: ThemeService,
@@ -100,24 +105,24 @@ export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends
100105
this.dso = this.linkService.resolveLink(this.dso, followLink('item'));
101106
this.item$ = (this.dso.item as Observable<RemoteData<Item>>).pipe(getAllSucceededRemoteData(), getRemoteDataPayload());
102107
this.item$.pipe(take(1)).subscribe((item: Item) => {
103-
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.getComponent(item));
108+
const component: GenericConstructor<Component> = this.getComponent(item);
104109

105110
const viewContainerRef = this.listableObjectDirective.viewContainerRef;
106111
viewContainerRef.clear();
107112

108-
const componentRef = viewContainerRef.createComponent(
109-
componentFactory,
110-
0,
111-
undefined,
112-
[
113+
this.compRef = viewContainerRef.createComponent(
114+
component, {
115+
index: 0,
116+
projectableNodes: [
113117
[this.badges.nativeElement],
114118
[this.buttons.nativeElement]
115-
]);
116-
(componentRef.instance as any).object = item;
117-
(componentRef.instance as any).index = this.index;
118-
(componentRef.instance as any).linkType = this.linkType;
119-
(componentRef.instance as any).listID = this.listID;
120-
componentRef.changeDetectorRef.detectChanges();
119+
],
120+
});
121+
this.compRef.setInput('object', item);
122+
this.compRef.setInput('index', this.index);
123+
this.compRef.setInput('linkType', this.linkType);
124+
this.compRef.setInput('listID', this.listID);
125+
this.compRef.changeDetectorRef.detectChanges();
121126
}
122127
);
123128

@@ -130,6 +135,13 @@ export class WorkspaceItemSearchResultAdminWorkflowGridElementComponent extends
130135
});
131136
}
132137

138+
ngOnDestroy(): void {
139+
if (hasValue(this.compRef)) {
140+
this.compRef.destroy();
141+
this.compRef = undefined;
142+
}
143+
}
144+
133145
/**
134146
* Fetch the component depending on the item's entity type, view mode and context
135147
* @returns {GenericConstructor<Component>}

src/app/shared/context-help.directive.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
ComponentFactoryResolver,
32
ComponentRef,
43
Directive,
54
Input,
@@ -12,6 +11,7 @@ import { PlacementArray } from '@ng-bootstrap/ng-bootstrap/util/positioning';
1211
import { ContextHelpWrapperComponent } from './context-help-wrapper/context-help-wrapper.component';
1312
import { PlacementDir } from './context-help-wrapper/placement-dir.model';
1413
import { ContextHelpService } from './context-help.service';
14+
import { hasValue } from './empty.util';
1515

1616
export interface ContextHelpDirectiveInput {
1717
content: string;
@@ -43,7 +43,6 @@ export class ContextHelpDirective implements OnChanges, OnDestroy {
4343
constructor(
4444
private templateRef: TemplateRef<any>,
4545
private viewContainerRef: ViewContainerRef,
46-
private componentFactoryResolver: ComponentFactoryResolver,
4746
private contextHelpService: ContextHelpService
4847
) {}
4948

@@ -53,19 +52,21 @@ export class ContextHelpDirective implements OnChanges, OnDestroy {
5352
this.contextHelpService.add({id: this.dsContextHelp.id, isTooltipVisible: false});
5453

5554
if (this.wrapper === undefined) {
56-
const factory
57-
= this.componentFactoryResolver.resolveComponentFactory(ContextHelpWrapperComponent);
58-
this.wrapper = this.viewContainerRef.createComponent(factory);
55+
this.wrapper = this.viewContainerRef.createComponent(ContextHelpWrapperComponent);
5956
}
60-
this.wrapper.instance.templateRef = this.templateRef;
61-
this.wrapper.instance.content = this.dsContextHelp.content;
62-
this.wrapper.instance.id = this.dsContextHelp.id;
63-
this.wrapper.instance.tooltipPlacement = this.dsContextHelp.tooltipPlacement;
64-
this.wrapper.instance.iconPlacement = this.dsContextHelp.iconPlacement;
57+
this.wrapper.setInput('templateRef', this.templateRef);
58+
this.wrapper.setInput('content', this.dsContextHelp.content);
59+
this.wrapper.setInput('id', this.dsContextHelp.id);
60+
this.wrapper.setInput('tooltipPlacement', this.dsContextHelp.tooltipPlacement);
61+
this.wrapper.setInput('iconPlacement', this.dsContextHelp.iconPlacement);
6562
}
6663

6764
ngOnDestroy() {
6865
this.clearMostRecentId();
66+
if (hasValue(this.wrapper)) {
67+
this.wrapper.destroy();
68+
this.wrapper = undefined;
69+
}
6970
}
7071

7172
private clearMostRecentId(): void {

src/app/workflowitems-edit-page/advanced-workflow-action/advanced-workflow-actions-loader/advanced-workflow-actions-loader.component.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, Input, ViewChild, ComponentFactoryResolver, OnInit } from '@angular/core';
1+
import { Component, Input, ViewChild, OnInit, ComponentRef, OnDestroy } from '@angular/core';
22
import { hasValue } from '../../../shared/empty.util';
33
import {
44
getAdvancedComponentByWorkflowTaskOption
@@ -15,7 +15,7 @@ import { PAGE_NOT_FOUND_PATH } from '../../../app-routing-paths';
1515
templateUrl: './advanced-workflow-actions-loader.component.html',
1616
styleUrls: ['./advanced-workflow-actions-loader.component.scss'],
1717
})
18-
export class AdvancedWorkflowActionsLoaderComponent implements OnInit {
18+
export class AdvancedWorkflowActionsLoaderComponent implements OnDestroy, OnInit {
1919

2020
/**
2121
* The name of the type to render
@@ -28,8 +28,12 @@ export class AdvancedWorkflowActionsLoaderComponent implements OnInit {
2828
*/
2929
@ViewChild(AdvancedWorkflowActionsDirective, { static: true }) claimedTaskActionsDirective: AdvancedWorkflowActionsDirective;
3030

31+
/**
32+
* The reference to the dynamic component
33+
*/
34+
protected compRef: ComponentRef<Component>;
35+
3136
constructor(
32-
private componentFactoryResolver: ComponentFactoryResolver,
3337
private router: Router,
3438
) {
3539
}
@@ -40,16 +44,24 @@ export class AdvancedWorkflowActionsLoaderComponent implements OnInit {
4044
ngOnInit(): void {
4145
const comp = this.getComponentByWorkflowTaskOption(this.type);
4246
if (hasValue(comp)) {
43-
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(comp);
44-
4547
const viewContainerRef = this.claimedTaskActionsDirective.viewContainerRef;
4648
viewContainerRef.clear();
47-
viewContainerRef.createComponent(componentFactory);
49+
this.compRef = viewContainerRef.createComponent(comp);
4850
} else {
4951
void this.router.navigate([PAGE_NOT_FOUND_PATH]);
5052
}
5153
}
5254

55+
/**
56+
* Destroy the dynamically created component
57+
*/
58+
ngOnDestroy(): void {
59+
if (hasValue(this.compRef)) {
60+
this.compRef.destroy();
61+
this.compRef = undefined;
62+
}
63+
}
64+
5365
getComponentByWorkflowTaskOption(type: string): any {
5466
return getAdvancedComponentByWorkflowTaskOption(type);
5567
}

0 commit comments

Comments
 (0)