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 { Component, OnChanges, OnInit, Input } from '@angular/core';
|
||||||
import { Subscription } from 'rxjs';
|
|
||||||
import { GenericConstructor } from 'src/app/core/shared/generic-constructor';
|
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 { getSearchLabelByOperator } from './search-label-loader.decorator';
|
||||||
import { AppliedFilter } from '../../models/applied-filter.model';
|
import { AppliedFilter } from '../../models/applied-filter.model';
|
||||||
|
import { AbstractComponentLoaderComponent } from '../../../abstract-component-loader/abstract-component-loader.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-search-label-loader',
|
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() inPlaceSearch: boolean;
|
||||||
|
|
||||||
@Input() appliedFilter: AppliedFilter;
|
@Input() appliedFilter: AppliedFilter;
|
||||||
|
|
||||||
/**
|
protected inputNamesDependentForComponent: (keyof this & string)[] = [
|
||||||
* Directive to determine where the dynamic child component is located
|
'appliedFilter',
|
||||||
*/
|
];
|
||||||
@ViewChild(SearchLabelLoaderDirective, { static: true }) componentDirective: SearchLabelLoaderDirective;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)[] = [
|
protected inputNames: (keyof this & string)[] = [
|
||||||
'inPlaceSearch',
|
'inPlaceSearch',
|
||||||
'appliedFilter',
|
'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> {
|
public getComponent(): GenericConstructor<Component> {
|
||||||
return getSearchLabelByOperator(this.appliedFilter.operator);
|
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 { SearchFacetFilterComponent } from './search-filters/search-filter/search-facet-filter/search-facet-filter.component';
|
||||||
import { SearchLabelsComponent } from './search-labels/search-labels.component';
|
import { SearchLabelsComponent } from './search-labels/search-labels.component';
|
||||||
import { SearchLabelLoaderComponent } from './search-labels/search-label-loader/search-label-loader.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 { SearchLabelComponent } from './search-labels/search-label/search-label.component';
|
||||||
import { SearchLabelRangeComponent } from './search-labels/search-label-range/search-label-range.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';
|
import { SearchFacetFilterWrapperComponent } from './search-filters/search-filter/search-facet-filter-wrapper/search-facet-filter-wrapper.component';
|
||||||
@@ -86,7 +85,6 @@ export const MODELS = [
|
|||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
...COMPONENTS,
|
...COMPONENTS,
|
||||||
SearchLabelLoaderDirective,
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
@@ -99,7 +97,6 @@ export const MODELS = [
|
|||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
...COMPONENTS,
|
...COMPONENTS,
|
||||||
SearchLabelLoaderDirective,
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class SearchModule {
|
export class SearchModule {
|
||||||
|
Reference in New Issue
Block a user