Skip to content

Commit 82a8da6

Browse files
101577: Fixed ClaimedTaskActionsLoaderComponent not updating its @rendersWorkflowTaskOption components ngOnChanges
1 parent 2ca91fd commit 82a8da6

File tree

1 file changed

+54
-19
lines changed

1 file changed

+54
-19
lines changed

src/app/shared/mydspace-actions/claimed-task/switcher/claimed-task-actions-loader.component.ts

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@ import {
33
ComponentFactoryResolver,
44
EventEmitter,
55
Input,
6-
OnDestroy,
76
OnInit,
87
Output,
9-
ViewChild
8+
ViewChild,
9+
OnChanges,
10+
SimpleChanges,
11+
ComponentRef,
1012
} from '@angular/core';
1113
import { getComponentByWorkflowTaskOption } from './claimed-task-actions-decorator';
1214
import { ClaimedTask } from '../../../../core/tasks/models/claimed-task-object.model';
1315
import { ClaimedTaskActionsDirective } from './claimed-task-actions.directive';
14-
import { ClaimedTaskActionsAbstractComponent } from '../abstract/claimed-task-actions-abstract.component';
15-
import { hasValue } from '../../../empty.util';
16-
import { Subscription } from 'rxjs';
16+
import { hasValue, isNotEmpty, hasNoValue } from '../../../empty.util';
1717
import { MyDSpaceActionsResult } from '../../mydspace-actions';
18+
import { ClaimedTaskActionsAbstractComponent } from '../abstract/claimed-task-actions-abstract.component';
1819

1920
@Component({
2021
selector: 'ds-claimed-task-actions-loader',
@@ -24,7 +25,7 @@ import { MyDSpaceActionsResult } from '../../mydspace-actions';
2425
* Component for loading a ClaimedTaskAction component depending on the "option" input
2526
* Passes on the ClaimedTask to the component and subscribes to the processCompleted output
2627
*/
27-
export class ClaimedTaskActionsLoaderComponent implements OnInit, OnDestroy {
28+
export class ClaimedTaskActionsLoaderComponent implements OnInit, OnChanges {
2829
/**
2930
* The ClaimedTask object
3031
*/
@@ -47,10 +48,18 @@ export class ClaimedTaskActionsLoaderComponent implements OnInit, OnDestroy {
4748
@ViewChild(ClaimedTaskActionsDirective, {static: true}) claimedTaskActionsDirective: ClaimedTaskActionsDirective;
4849

4950
/**
50-
* Array to track all subscriptions and unsubscribe them onDestroy
51-
* @type {Array}
51+
* The reference to the dynamic component
5252
*/
53-
protected subs: Subscription[] = [];
53+
protected compRef: ComponentRef<Component>;
54+
55+
/**
56+
* The list of input and output names for the dynamic component
57+
*/
58+
protected inAndOutputNames: (keyof ClaimedTaskActionsAbstractComponent & keyof this)[] = [
59+
'object',
60+
'option',
61+
'processCompleted',
62+
];
5463

5564
constructor(private componentFactoryResolver: ComponentFactoryResolver) {
5665
}
@@ -59,19 +68,42 @@ export class ClaimedTaskActionsLoaderComponent implements OnInit, OnDestroy {
5968
* Fetch, create and initialize the relevant component
6069
*/
6170
ngOnInit(): void {
71+
this.instantiateComponent();
72+
}
73+
74+
/**
75+
* Whenever the inputs change, update the inputs of the dynamic component
76+
*/
77+
ngOnChanges(changes: SimpleChanges): void {
78+
if (hasNoValue(this.compRef)) {
79+
// sometimes the component has not been initialized yet, so it first needs to be initialized
80+
// before being called again
81+
this.instantiateComponent(changes);
82+
} else {
83+
// if an input or output has changed
84+
if (this.inAndOutputNames.some((name: any) => hasValue(changes[name]))) {
85+
this.connectInputsAndOutputs();
86+
if (this.compRef?.instance && 'ngOnChanges' in this.compRef.instance) {
87+
(this.compRef.instance as any).ngOnChanges(changes);
88+
}
89+
}
90+
}
91+
}
6292

93+
private instantiateComponent(changes?: SimpleChanges): void {
6394
const comp = this.getComponentByWorkflowTaskOption(this.option);
6495
if (hasValue(comp)) {
6596
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(comp);
6697

6798
const viewContainerRef = this.claimedTaskActionsDirective.viewContainerRef;
6899
viewContainerRef.clear();
69100

70-
const componentRef = viewContainerRef.createComponent(componentFactory);
71-
const componentInstance = (componentRef.instance as ClaimedTaskActionsAbstractComponent);
72-
componentInstance.object = this.object;
73-
if (hasValue(componentInstance.processCompleted)) {
74-
this.subs.push(componentInstance.processCompleted.subscribe((result) => this.processCompleted.emit(result)));
101+
this.compRef = viewContainerRef.createComponent(componentFactory);
102+
103+
if (hasValue(changes)) {
104+
this.ngOnChanges(changes);
105+
} else {
106+
this.connectInputsAndOutputs();
75107
}
76108
}
77109
}
@@ -81,11 +113,14 @@ export class ClaimedTaskActionsLoaderComponent implements OnInit, OnDestroy {
81113
}
82114

83115
/**
84-
* Unsubscribe from open subscriptions
116+
* Connect the in and outputs of this component to the dynamic component,
117+
* to ensure they're in sync
85118
*/
86-
ngOnDestroy(): void {
87-
this.subs
88-
.filter((subscription) => hasValue(subscription))
89-
.forEach((subscription) => subscription.unsubscribe());
119+
protected connectInputsAndOutputs(): void {
120+
if (isNotEmpty(this.inAndOutputNames) && hasValue(this.compRef) && hasValue(this.compRef.instance)) {
121+
this.inAndOutputNames.filter((name: any) => this[name] !== undefined).forEach((name: any) => {
122+
this.compRef.instance[name] = this[name];
123+
});
124+
}
90125
}
91126
}

0 commit comments

Comments
 (0)