如何为 tabPanel 定义静态索引
How to define static index for tabPanel
我正在使用 PrimeNG tabView
组件来显示步骤,假设我有 3 个步骤 [1,2,3],并且我正在使用 handleTabViewChange(e)
使用步骤的索引加载数据
对应的索引是[0,1,2],第2步有条件显示,不显示时我有2步[1 ,3] with index [0,1], 所以第3步的index变为[1] :
有没有办法为每个选项卡设置一个静态索引,所以当第2步不显示时,第3步的索引保持不变[2]:
<p-tabView (onChange)="handleTabViewChange($event)">
<p-tabPanel header="Step 1" >
</p-tabPanel>
<p-tabPanel header="Step 2" *ngIf="false" >
</p-tabPanel>
<p-tabPanel header="Step 3" >
</p-tabPanel>
</p-tabView>
handleTabViewChange(e):
data: any[];
handleTabViewChange(e) {
var step= e.index + 1;
this.data = this.loadData(step);
}
您可以通过使用向面板添加静态 index
属性 的指令,并使用 ViewChildren
枚举呈现的面板来执行此操作:
指令:
@Directive({
selector: 'p-tabPanel'
})
export class MyTabPanelDirective {
@Input() index: number;
constructor() {}
}
模板中的选项卡视图应如下所示:
<p-tabView (onChange)="handleTabViewChange($event)">
<p-tabPanel header="Step 1" [index]="0">
</p-tabPanel>
<p-tabPanel header="Step 2" [index]="1" *ngIf="false" >
</p-tabPanel>
<p-tabPanel header="Step 3" [index]="2" >
</p-tabPanel>
</p-tabView>
最后您的组件可以像这样处理 onChange
:
@ViewChildren(MyTabPanelDirective) panels: QueryList<MyTabPanelDirective>;
handleTabViewChange(e) {
const step = this.panels.get(e.index + 1).index;
this.data = this.loadData(step);
}
它的工作方式是事件参数包括 DOM 中面板的索引,这与视图子查询列表相匹配(有一个警告,见下文)。然后在事件处理程序中,我们获取 DOM 索引,加 1,并从指令中提取静态索引。
注意事项 1 如果您在代码中操作选项卡面板,通过添加、删除或重新排序,则查询列表顺序可能与 DOM 顺序不匹配。
注意事项 2 如果您在同一个模板中有两个选项卡视图,则必须稍作更改。
警告 #2 的解决方案
多个选项卡视图
使用选项卡视图提供的服务(因此每个选项卡视图都有自己的实例)- 并将其注入面板。然后每个面板将自己注册到该服务,这将根据 DOM 的顺序进行(至少在最初,请参见警告 #1)。
然后在事件处理程序中,通过索引查询面板视图的选项卡服务。
服务:
@Injectable({ providedIn: 'root' })
export class TabRepoService {
panels: MyTabPanelDirective[] = [];
constructor() {}
addPanel(panel: MyTabPanelDirective) {
this.panels.push(panel);
}
}
选项卡视图指令附加到所有选项卡视图并为其自身及其子项(面板)创建服务实例:
@Directive({
selector: 'p-tabView',
exportAs: 'myTabView',
// This means there will be a separate instance per tab view
providers: [TabRepoService]
})
export class MyTabViewDirective {
constructor(public repo: TabRepoService) {}
getPanelAtIndex(i: number) {
return this.repo.panels[i];
}
}
接下来,修改面板指令,使用此服务来注册自己:
@Directive({
selector: 'p-tabPanel',
})
export class MyTabPanelDirective {
@Input() index: number;
constructor(private repo: TabRepoService) {
repo.addPanel(this);
}
}
html用法:
<p-tabView #tab1="myTabView" (onChange)="handleTabViewChange($event, tab1)">
<p-tabPanel header="Header 1" [index]="0">
Content 1
</p-tabPanel>
<p-tabPanel header="Header 2" [index]="1" *ngIf="false">
Content 2
</p-tabPanel>
<p-tabPanel header="Header 3" [index]="2">
Content 3
</p-tabPanel>
</p-tabView>
请注意,我们将选项卡视图指令传递给事件处理程序,以便它可以通过索引查询它的子项。
最后是事件处理程序:
handleTabViewChange(e, t: MyTabViewDirective) {
const step = t.getPanelAtIndex(e.index).index;
this.data = this.loadData(step);
}
注意:在此解决方案中 ViewChildren
不是必需的。
我正在使用 PrimeNG tabView
组件来显示步骤,假设我有 3 个步骤 [1,2,3],并且我正在使用 handleTabViewChange(e)
使用步骤的索引加载数据
对应的索引是[0,1,2],第2步有条件显示,不显示时我有2步[1 ,3] with index [0,1], 所以第3步的index变为[1] :
有没有办法为每个选项卡设置一个静态索引,所以当第2步不显示时,第3步的索引保持不变[2]:
<p-tabView (onChange)="handleTabViewChange($event)">
<p-tabPanel header="Step 1" >
</p-tabPanel>
<p-tabPanel header="Step 2" *ngIf="false" >
</p-tabPanel>
<p-tabPanel header="Step 3" >
</p-tabPanel>
</p-tabView>
handleTabViewChange(e):
data: any[];
handleTabViewChange(e) {
var step= e.index + 1;
this.data = this.loadData(step);
}
您可以通过使用向面板添加静态 index
属性 的指令,并使用 ViewChildren
枚举呈现的面板来执行此操作:
指令:
@Directive({
selector: 'p-tabPanel'
})
export class MyTabPanelDirective {
@Input() index: number;
constructor() {}
}
模板中的选项卡视图应如下所示:
<p-tabView (onChange)="handleTabViewChange($event)">
<p-tabPanel header="Step 1" [index]="0">
</p-tabPanel>
<p-tabPanel header="Step 2" [index]="1" *ngIf="false" >
</p-tabPanel>
<p-tabPanel header="Step 3" [index]="2" >
</p-tabPanel>
</p-tabView>
最后您的组件可以像这样处理 onChange
:
@ViewChildren(MyTabPanelDirective) panels: QueryList<MyTabPanelDirective>;
handleTabViewChange(e) {
const step = this.panels.get(e.index + 1).index;
this.data = this.loadData(step);
}
它的工作方式是事件参数包括 DOM 中面板的索引,这与视图子查询列表相匹配(有一个警告,见下文)。然后在事件处理程序中,我们获取 DOM 索引,加 1,并从指令中提取静态索引。
注意事项 1 如果您在代码中操作选项卡面板,通过添加、删除或重新排序,则查询列表顺序可能与 DOM 顺序不匹配。
注意事项 2 如果您在同一个模板中有两个选项卡视图,则必须稍作更改。
警告 #2 的解决方案
多个选项卡视图
使用选项卡视图提供的服务(因此每个选项卡视图都有自己的实例)- 并将其注入面板。然后每个面板将自己注册到该服务,这将根据 DOM 的顺序进行(至少在最初,请参见警告 #1)。
然后在事件处理程序中,通过索引查询面板视图的选项卡服务。
服务:
@Injectable({ providedIn: 'root' })
export class TabRepoService {
panels: MyTabPanelDirective[] = [];
constructor() {}
addPanel(panel: MyTabPanelDirective) {
this.panels.push(panel);
}
}
选项卡视图指令附加到所有选项卡视图并为其自身及其子项(面板)创建服务实例:
@Directive({
selector: 'p-tabView',
exportAs: 'myTabView',
// This means there will be a separate instance per tab view
providers: [TabRepoService]
})
export class MyTabViewDirective {
constructor(public repo: TabRepoService) {}
getPanelAtIndex(i: number) {
return this.repo.panels[i];
}
}
接下来,修改面板指令,使用此服务来注册自己:
@Directive({
selector: 'p-tabPanel',
})
export class MyTabPanelDirective {
@Input() index: number;
constructor(private repo: TabRepoService) {
repo.addPanel(this);
}
}
html用法:
<p-tabView #tab1="myTabView" (onChange)="handleTabViewChange($event, tab1)">
<p-tabPanel header="Header 1" [index]="0">
Content 1
</p-tabPanel>
<p-tabPanel header="Header 2" [index]="1" *ngIf="false">
Content 2
</p-tabPanel>
<p-tabPanel header="Header 3" [index]="2">
Content 3
</p-tabPanel>
</p-tabView>
请注意,我们将选项卡视图指令传递给事件处理程序,以便它可以通过索引查询它的子项。
最后是事件处理程序:
handleTabViewChange(e, t: MyTabViewDirective) {
const step = t.getPanelAtIndex(e.index).index;
this.data = this.loadData(step);
}
注意:在此解决方案中 ViewChildren
不是必需的。