Eu sei que os Sinais Angulares podem ser usados neste caso em particular para evitar chamar a função isVisible constantemente. Mas não tenho experiência com esse novo recurso e não consigo descobrir o que mudar no meu código para aproveitar os Sinais. Colei um trecho simplificado do meu código abaixo, apenas para a ideia geral.
O que devo mudar para que isso funcione com o Signals?
visibleSections = [];
sectionConfig = [
{
name: 'someComponent',
hidden: false
},
{
name: 'otherComponent',
hidden: false
}
];
ngOnInit() {
this.visibleSections = this.sectionConfig.filter(c => !c.hidden);
}
public isVisible(section): boolean {
return this.visibleSections.findIndex(s => s.name === section) > -1;
}
public setSectionVisibility(e: any): void {
this.sectionConfig.find(c => c.name === e.itemValue.name).hidden = e.value.findIndex(p => p === e.itemValue) === -1;
}
HTML:
<p-multiSelect
#multiselect
defaultLabel="Show/hide sections"
optionLabel="title"
name="show-hide-sections"
scrollHeight="300px"
styleClass="multiselect-as-button mr-3 ml-3"
dropdownIcon="fas fa-bars rotate-90"
[options]="sectionConfig"
[(ngModel)]="visibleSections"
[displaySelectedLabel]="false"
(onChange)="setSectionVisibility($event)"
[style]="{ width: '208px' }"
[showHeader]="false"
[appendTo]="'body'"></p-multiSelect>
@if (isVisible("someComponent")) {
<some-component></some-component>
}
@if (isVisible("otherComponent")) {
<other-component></other-component>
}
[EDITAR]
Seguindo as duas respostas muito boas abaixo, e considerando que ainda estou usando o Angular 18 e não posso usar o LinkedSignal por enquanto, foi assim que acabei fazendo:
TS:
type Config = { name: string; hidden: boolean; };
const sectionConfig = signal<Config[]>([ {
name: 'someComponent',
hidden: false,
},
{
name: 'otherComponent',
hidden: false
}]);
visibleSections = computed(() => {
const sections = this.sectionConfig();
return sections.filter(s => !s.hidden);
});
public visibleSectionsFlags = computed(() => {
return this.sectionConfig()
.filter((item: any) => !item.hidden)
.map((item: any) => item.name);
});
public setSectionVisibility(e: any): void {
this.sectionConfig.update((sectionConfig: any) => {
const foundIndex = this.sectionConfig().findIndex(c => c.name === e.itemValue.name);
if (foundIndex > -1) {
sectionConfig[foundIndex].hidden = !sectionConfig[foundIndex].hidden;
}
return [...sectionConfig];
});
}
HTML:
<p-multiSelect
#multiselect
defaultLabel="Show/hide sections"
optionLabel="title"
name="show-hide-sections"
scrollHeight="300px"
styleClass="multiselect-as-button mr-3 ml-3"
dropdownIcon="fas fa-bars rotate-90"
[options]="sectionConfig()"
[ngModel]="visibleSections()"
[displaySelectedLabel]="false"
(onChange)="setSectionVisibility($event)"
[style]="{ width: '208px' }"
[showHeader]="false"
[appendTo]="'body'"></p-multiSelect>
@if (visibleSectionsFlags().includes("someComponent")) {
<app-some-component></app-some-component>
}