I've been working on a way of not doing a lots of *ngIf
that depends on a type selected by the user
<select [(ngModel)]="type" name="type">
<option value="a">Type A</option>
<option value="b">Type B</option>
</select>
<div *ngIf="type === 'a'">
logic...
</div>
<div *ngIf="type === 'b'">
logic...
</div>
So i endedup doing this, and i want to know if there exists a simplier way
some-service.ts
export const TYPE_MAP = {};
export class SomeService {
typeMap = TYPE_MAP;
constructor() {
}
}
type-manager.interface.ts
export interface TypeManager {
someMethod();
}
type-manager.decorator.ts
export function TypeManagerDecorator(aType: string) {
return function _TypeManagerDecorator<T extends { new(...args: any[]): TypeManager}>(constr: T) {
TYPE_MAP[aType] = constr;
};
}
manager-for-type-a.component.ts
@TypeManagerDecorator('a')
@Component({
selector: 'app-manager-for-type-a',
templateUrl: './manager-for-type-a.component.html',
styleUrls: ['./manager-for-type-a.component.css'],
viewProviders: [
{
provide: ControlContainer,
useExisting: NgForm
}
]
})
export class ManagerForTypeAComponent implements OnInit, TypeManager {
constructor() {
}
ngOnInit() {
};
someMethod() {
};
}
manager-for-type-b.component.ts
@TypeManagerDecorator('b')
@Component({
selector: 'app-manager-for-type-b',
templateUrl: './manager-for-type-b.component.html',
styleUrls: ['./manager-for-type-b.component.css'],
viewProviders: [
{
provide: ControlContainer,
useExisting: NgForm
}
]
})
export class ManagerForTypeBComponent implements OnInit, TypeManager {
constructor() {
}
ngOnInit() {
};
someMethod() {
};
}
main.component.html
<form #form="ngForm" (ngSubmit)="form.valid" autocomplete="off">
<select [(ngModel)]="type" name="type" (ngModelChange)="changeTypeManager($event)">
<option value="a">Type A</option>
<option value="b">Type B</option>
</select>
<ng-container #container></ng-container>
</form>
main.component.ts
@Component({
selector: 'app-main',
templateUrl: './main.component.html',
styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit, OnDestroy {
@ViewChild('main', {read: ViewContainerRef, static: true})
private mainContainer: ViewContainerRef;
private componentReference: ComponentRef<any>;
constructor(
private aService: SomeService,
private resolver: ComponentFactoryResolver
) {
}
ngOnInit() {
}
private changeTypeManager(aType: string) {
if(this.componentReference) {
this.componentReference.destroy();
}
if(!this.aService.typeMap[aType]) {
throw new Error(`No class exists with the decorator @TypeManagerDecorator('${aType}')`);
}
const componentFactory = this.resolver.resolveComponentFactory(this.aService.typeMap[aType]);
this.componentReference = this.mainContainer.createComponent(componentFactory);
}
}
Aucun commentaire:
Enregistrer un commentaire