mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
110889: Made the SearchLabelLoaderComponent extend AbstractComponentLoaderComponent
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
import { Directive, ViewContainerRef } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Directive used as a hook to know where to inject the dynamic loaded component
|
||||
*/
|
||||
@Directive({
|
||||
selector: '[dsSearchLabelLoader]'
|
||||
})
|
||||
export class SearchLabelLoaderDirective {
|
||||
|
||||
constructor(
|
||||
public viewContainerRef: ViewContainerRef,
|
||||
) {
|
||||
}
|
||||
|
||||
}
|
@@ -1 +0,0 @@
|
||||
<ng-template dsSearchLabelLoader></ng-template>
|
@@ -1,132 +1,30 @@
|
||||
import { Component, ComponentRef, OnChanges, OnDestroy, OnInit, ViewChild, ViewContainerRef, SimpleChanges, Input } from '@angular/core';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Component, OnChanges, OnInit, Input } from '@angular/core';
|
||||
import { GenericConstructor } from 'src/app/core/shared/generic-constructor';
|
||||
import { hasValue, isNotEmpty } from 'src/app/shared/empty.util';
|
||||
import { ThemeService } from '../../../theme-support/theme.service';
|
||||
import { SearchLabelLoaderDirective } from './search-label-loader-directive.directive';
|
||||
import { getSearchLabelByOperator } from './search-label-loader.decorator';
|
||||
import { AppliedFilter } from '../../models/applied-filter.model';
|
||||
import { AbstractComponentLoaderComponent } from '../../../abstract-component-loader/abstract-component-loader.component';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-search-label-loader',
|
||||
templateUrl: './search-label-loader.component.html',
|
||||
templateUrl: '../../../abstract-component-loader/abstract-component-loader.component.html',
|
||||
})
|
||||
export class SearchLabelLoaderComponent implements OnInit, OnChanges, OnDestroy {
|
||||
export class SearchLabelLoaderComponent extends AbstractComponentLoaderComponent<Component> implements OnInit, OnChanges {
|
||||
|
||||
@Input() inPlaceSearch: boolean;
|
||||
|
||||
@Input() appliedFilter: AppliedFilter;
|
||||
|
||||
/**
|
||||
* Directive to determine where the dynamic child component is located
|
||||
*/
|
||||
@ViewChild(SearchLabelLoaderDirective, { static: true }) componentDirective: SearchLabelLoaderDirective;
|
||||
protected inputNamesDependentForComponent: (keyof this & string)[] = [
|
||||
'appliedFilter',
|
||||
];
|
||||
|
||||
/**
|
||||
* The reference to the dynamic component
|
||||
*/
|
||||
protected compRef: ComponentRef<Component>;
|
||||
|
||||
/**
|
||||
* Array to track all subscriptions and unsubscribe them onDestroy
|
||||
*/
|
||||
protected subs: Subscription[] = [];
|
||||
|
||||
/**
|
||||
* The @Input() that are used to find the matching component using {@link getComponent}. When the value of
|
||||
* one of these @Input() change this loader needs to retrieve the best matching component again using the
|
||||
* {@link getComponent} method.
|
||||
*/
|
||||
protected inputNamesDependentForComponent: (keyof this & string)[] = [];
|
||||
|
||||
/**
|
||||
* The list of the @Input() names that should be passed down to the dynamically created components.
|
||||
*/
|
||||
protected inputNames: (keyof this & string)[] = [
|
||||
'inPlaceSearch',
|
||||
'appliedFilter',
|
||||
];
|
||||
|
||||
constructor(
|
||||
protected themeService: ThemeService,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the dynamic child component
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.instantiateComponent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whenever the inputs change, update the inputs of the dynamic component
|
||||
*/
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (hasValue(this.compRef)) {
|
||||
if (this.inputNamesDependentForComponent.some((name: keyof this & string) => hasValue(changes[name]) && changes[name].previousValue !== changes[name].currentValue)) {
|
||||
// Recreate the component when the @Input()s used by getComponent() aren't up-to-date anymore
|
||||
this.destroyComponentInstance();
|
||||
this.instantiateComponent();
|
||||
} else {
|
||||
this.connectInputsAndOutputs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.subs
|
||||
.filter((subscription: Subscription) => hasValue(subscription))
|
||||
.forEach((subscription: Subscription) => subscription.unsubscribe());
|
||||
this.destroyComponentInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the component and connects the @Input() & @Output() from the ThemedComponent to its child Component.
|
||||
*/
|
||||
public instantiateComponent(): void {
|
||||
const component: GenericConstructor<Component> = this.getComponent();
|
||||
|
||||
const viewContainerRef: ViewContainerRef = this.componentDirective.viewContainerRef;
|
||||
viewContainerRef.clear();
|
||||
|
||||
this.compRef = viewContainerRef.createComponent(
|
||||
component, {
|
||||
index: 0,
|
||||
injector: undefined,
|
||||
},
|
||||
);
|
||||
|
||||
this.connectInputsAndOutputs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the themed component and calls it's `ngOnDestroy`
|
||||
*/
|
||||
public destroyComponentInstance(): void {
|
||||
if (hasValue(this.compRef)) {
|
||||
this.compRef.destroy();
|
||||
this.compRef = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the component depending on the item's entity type, metadata representation type and context
|
||||
*/
|
||||
public getComponent(): GenericConstructor<Component> {
|
||||
return getSearchLabelByOperator(this.appliedFilter.operator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect the inputs and outputs of this component to the dynamic component,
|
||||
* to ensure they're in sync
|
||||
*/
|
||||
public connectInputsAndOutputs(): void {
|
||||
if (isNotEmpty(this.inputNames) && hasValue(this.compRef) && hasValue(this.compRef.instance)) {
|
||||
this.inputNames.filter((name: string) => this[name] !== undefined).filter((name: string) => this[name] !== this.compRef.instance[name]).forEach((name: string) => {
|
||||
this.compRef.instance[name] = this[name];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@ import { SearchFilterComponent } from './search-filters/search-filter/search-fil
|
||||
import { SearchFacetFilterComponent } from './search-filters/search-filter/search-facet-filter/search-facet-filter.component';
|
||||
import { SearchLabelsComponent } from './search-labels/search-labels.component';
|
||||
import { SearchLabelLoaderComponent } from './search-labels/search-label-loader/search-label-loader.component';
|
||||
import { SearchLabelLoaderDirective } from './search-labels/search-label-loader/search-label-loader-directive.directive';
|
||||
import { SearchLabelComponent } from './search-labels/search-label/search-label.component';
|
||||
import { SearchLabelRangeComponent } from './search-labels/search-label-range/search-label-range.component';
|
||||
import { SearchFacetFilterWrapperComponent } from './search-filters/search-filter/search-facet-filter-wrapper/search-facet-filter-wrapper.component';
|
||||
@@ -86,7 +85,6 @@ export const MODELS = [
|
||||
@NgModule({
|
||||
declarations: [
|
||||
...COMPONENTS,
|
||||
SearchLabelLoaderDirective,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
@@ -99,7 +97,6 @@ export const MODELS = [
|
||||
],
|
||||
exports: [
|
||||
...COMPONENTS,
|
||||
SearchLabelLoaderDirective,
|
||||
]
|
||||
})
|
||||
export class SearchModule {
|
||||
|
Reference in New Issue
Block a user