我知道在这种特殊情况下可以使用 Angular Signals 来避免不断调用 isVisible 函数。但我没有使用过这个新功能,也不知道该在代码中做哪些更改才能利用 Signals。我在下面粘贴了一段简化的代码,仅供参考。
我应该进行哪些更改才能使其与 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>
}
[编辑]
遵循下面两个非常好的答案,并考虑到我仍然在使用 angular 18 并且暂时不能使用 linkedSignal,这就是我最终的做法:
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>
}