Commits

Giuseppe Digilio authored a6d29f5a236
[CST-6876] Replace deprecated createComponent method and improve code
No tags

src/app/shared/object-collection/shared/listable-object/listable-object-component-loader.component.ts

Modified
1 1 import {
2 + ChangeDetectorRef,
2 3 Component,
3 - ComponentFactoryResolver,
4 4 ComponentRef,
5 5 ElementRef,
6 6 EventEmitter,
7 7 Input,
8 8 OnChanges,
9 9 OnDestroy,
10 10 OnInit,
11 11 Output,
12 12 SimpleChanges,
13 13 ViewChild
14 14 } from '@angular/core';
15 +
16 +import { Subscription } from 'rxjs';
17 +import { debounceTime, take } from 'rxjs/operators';
18 +
15 19 import { ListableObject } from '../listable-object.model';
16 20 import { ViewMode } from '../../../../core/shared/view-mode.model';
17 21 import { Context } from '../../../../core/shared/context.model';
18 22 import { getListableObjectComponent } from './listable-object.decorator';
19 23 import { GenericConstructor } from '../../../../core/shared/generic-constructor';
20 24 import { ListableObjectDirective } from './listable-object.directive';
21 25 import { CollectionElementLinkType } from '../../collection-element-link.type';
22 26 import { hasValue, isNotEmpty } from '../../../empty.util';
23 -import { Subscription } from 'rxjs';
24 27 import { DSpaceObject } from '../../../../core/shared/dspace-object.model';
25 -import { take } from 'rxjs/operators';
26 28 import { ThemeService } from '../../../theme-support/theme.service';
27 29
28 30 @Component({
29 31 selector: 'ds-listable-object-component-loader',
30 32 styleUrls: ['./listable-object-component-loader.component.scss'],
31 33 templateUrl: './listable-object-component-loader.component.html'
32 34 })
33 35 /**
34 36 * Component for determining what component to use depending on the item's entity type (dspace.entity.type)
35 37 */
75 77 @Input() value: string;
76 78
77 79 /**
78 80 * Whether or not informational badges (e.g. Private, Withdrawn) should be hidden
79 81 */
80 82 @Input() hideBadges = false;
81 83
82 84 /**
83 85 * Directive hook used to place the dynamic child component
84 86 */
85 - @ViewChild(ListableObjectDirective, {static: true}) listableObjectDirective: ListableObjectDirective;
87 + @ViewChild(ListableObjectDirective, { static: true }) listableObjectDirective: ListableObjectDirective;
86 88
87 89 /**
88 90 * View on the badges template, to be passed on to the loaded component (which will place the badges in the desired
89 91 * location, or on top if not specified)
90 92 */
91 93 @ViewChild('badges', { static: true }) badges: ElementRef;
92 94
93 95 /**
94 96 * Emit when the listable object has been reloaded.
95 97 */
113 115
114 116 /**
115 117 * The reference to the dynamic component
116 118 */
117 119 protected compRef: ComponentRef<Component>;
118 120
119 121 /**
120 122 * The list of input and output names for the dynamic component
121 123 */
122 124 protected inAndOutputNames: string[] = [
123 - 'object',
124 - 'index',
125 - 'linkType',
126 - 'listID',
127 - 'showLabel',
128 - 'context',
129 - 'viewMode',
130 - 'value',
131 - 'hideBadges',
132 - 'contentChange',
133 - ];
134 -
135 - constructor(
136 - private componentFactoryResolver: ComponentFactoryResolver,
137 - private themeService: ThemeService
138 - ) {
125 + 'object',
126 + 'index',
127 + 'linkType',
128 + 'listID',
129 + 'showLabel',
130 + 'context',
131 + 'viewMode',
132 + 'value',
133 + 'hideBadges',
134 + 'contentChange',
135 + ];
136 +
137 + constructor(private cdr: ChangeDetectorRef, private themeService: ThemeService) {
139 138 }
140 139
141 140 /**
142 141 * Setup the dynamic child component
143 142 */
144 143 ngOnInit(): void {
145 144 this.instantiateComponent(this.object);
146 145 }
147 146
148 147 /**
159 158 .filter((subscription) => hasValue(subscription))
160 159 .forEach((subscription) => subscription.unsubscribe());
161 160 }
162 161
163 162 private instantiateComponent(object) {
164 163
165 164 this.initBadges();
166 165
167 166 const component = this.getComponent(object.getRenderTypes(), this.viewMode, this.context);
168 167
169 - const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
170 -
171 168 const viewContainerRef = this.listableObjectDirective.viewContainerRef;
172 169 viewContainerRef.clear();
173 170
174 171 this.compRef = viewContainerRef.createComponent(
175 - componentFactory,
176 - 0,
177 - undefined,
178 - [
179 - [this.badges.nativeElement],
180 - ]);
172 + component, {
173 + index: 0,
174 + injector: undefined,
175 + projectableNodes: [
176 + [this.badges.nativeElement],
177 + ]
178 + }
179 + );
181 180
182 181 this.connectInputsAndOutputs();
183 182
184 183 if ((this.compRef.instance as any).reloadedObject) {
185 - (this.compRef.instance as any).reloadedObject.pipe(take(1)).subscribe((reloadedObject: DSpaceObject) => {
184 + (this.compRef.instance as any).reloadedObject.pipe(
185 + // Add delay before emitting event to allow the new object is elaborated on REST side
186 + debounceTime((100)),
187 + take(1)
188 + ).subscribe((reloadedObject: DSpaceObject) => {
186 189 if (reloadedObject) {
187 190 this.compRef.destroy();
188 191 this.object = reloadedObject;
189 192 this.instantiateComponent(reloadedObject);
190 - // Add delay before emitting event to allow the new object is instantiated
191 - setTimeout(() => {
192 - this.contentChange.emit(reloadedObject);
193 - }, 100);
193 + this.cdr.detectChanges();
194 + this.contentChange.emit(reloadedObject);
194 195 }
195 196 });
196 197 }
197 198 }
198 199
199 200 /**
200 201 * Initialize which badges should be visible in the listable component
201 202 */
202 203 initBadges() {
203 204 let objectAsAny = this.object as any;

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut