I'm trying to develope a tab component that recieve tabs dinamically by a service like that
@Injectable()
export class TabOfComponentService {
//some code
//add a tab in array and use a subject
addTab(tab: TabObject) {
tab.id = this.geraId();
this.tabs.push(tab);
this._subjectTab.next(this.tabs);
}
//remove a tab in array and use a subject
removeTab(tab: TabObject):TabObject[] {
let list: TabObject[] = [];
for (let t of this.tabs) {
if (!(tab.id === t.id)) {
list.push(t);
}
}
this.tabs=list;
this._subjectTab.next(this.tabs);
return list;
}
disableTabs(){
this._subjectDesabilitarAbas.next(true);
}
enableTabs(){
this._subjectDesabilitarAbas.next(false);
}
}
the object TabObject is like that
export class TabObject {
id: number;
type: Type<Component>;
classIcon: string;
cmpRef: ComponentRef<Component>;
titulo: string;
removivel: boolean;
desabilitado: boolean;
}
and for the component that build the tabs i wrote something like this
@Component
...
template: `
<div class="tab">
<div *ngFor="let item of tabs" class="tablinks" >
<button [ngClass]=" [((item.id===abaSelecionada?.id)?'active':'')]" (click)="abrirAba(item)" [disabled]="item.desabilitado || desabilitarAbas" >
<i [ngClass]="['fa', item.classIcon]" > </i>
{{item.titulo}}
<a *ngIf="item.removivel" (click)="removerAba(item)" title="Remover" style="padding-left:5px" >
<i class="fa fa-remove"> </i>
</a>
</button>
</div>
</div>
<div *ngFor="let item of tabs" [id]="item.id" [ngClass]="['tab'+item.id]" style=" display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none">
<dcl-wrapper [tabObject]="item" (onRemove)="removerAba($event)"></dcl-wrapper>
</div>
`
export class TabOfComponentComponent implements OnDestroy {
abaSelecionada: TabObject;
tabs: TabObject[];
desabilitarAbas: boolean;
subscriptionTabs: Subscription;
subscriptionDesabilitarAbas: Subscription;
constructor(private tabOfComponentService: TabOfComponentService, private elRef: ElementRef) {
this.tabs = [];
}
ngOnInit() {
this.subscriptionTabs = this.tabOfComponentService.subjectTab.subscribe(
(value) => {
this.setAbas(value);
},
error => console.error(error),
);
this.subscriptionDesabilitarAbas = this.tabOfComponentService.subjectDesabilitarAbas.subscribe(
(value) => {
this.desabilitarAbas = value;
}
);
this.abaSelecionada = null;
}
private setAbas(value: TabObject[]) {
this.tabs = value;
if (value && value.length > 0)
this.abrirAba(this.tabs[value.length - 1]);
}
ngOnDestroy() {
this.subscriptionTabs.unsubscribe();
this.subscriptionDesabilitarAbas.unsubscribe();
}
abrirAba(item: TabObject) {
let hElement: HTMLElement = this.elRef.nativeElement;
if (this.abaSelecionada) {
let divSelecionado: NodeListOf<Element> = hElement.getElementsByClassName("tab" + this.abaSelecionada.id);
(divSelecionado[0]).setAttribute("style", "display:none");
}
this.abaSelecionada = item;
let divs: NodeListOf<Element> = hElement.getElementsByClassName("tab" + item.id);
(divs[0]).setAttribute("style", "display:block");
}
if you realize i'm using a component that have a selector dcl-wrapper, i copyed the solution of the aswer of this topic with changes to don't destroy the componentRef Angular 2 dynamic tabs with user-click chosen components
I needed to insert all the components so that they always remain on the screen and when switching between tabs, it would simply make a display: none, all this because if I changed the presented component, I would lose the state of the component because it would be destroyed
Everything works the way I planned it, but there is a problem, so I can embed the components, it is necessary to declare them in the module using entryComponent, but these components are in lazy-loading modules.
Is there a way out of this?