带有 OnInitializedAsync 的选项卡?

Posted

技术标签:

【中文标题】带有 OnInitializedAsync 的选项卡?【英文标题】:Tabs with OnInitializedAsync? 【发布时间】:2021-01-27 03:23:43 【问题描述】:

考虑以下要求:

一个页面有tabs。 每个选项卡都有一个 Blazor 组件(即选项卡正文)以在单击时显示。 一些标签正文在初始化时运行OnInitializedAsync。 用户可以在选项卡之间切换以显示不同的选项卡正文。

但这就是挑战所在:

用户单击一个选项卡,切换到另一个选项卡,然后切换回他们单击的第一个选项卡。 (例如,用户单击第一个选项卡,然后切换到第二个选项卡,然后再次返回到第一个选项卡。) 标签正文在重新出现时不应被初始化两次。 (它不应运行 OnInitializedAsync 两次)。

这在 blazor 中怎么可能?

建议的解决方案:使用@if 来决定是否应该呈现每个选项卡

代码:

<ul class="nav nav-tabs">
    <li class="nav-item">
        <a class="nav-link" @onclick="() => tabId == 1">Tab 1</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" @onclick="() => tabId == 2">Tab 2</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" @onclick="() => tabId == 3">Tab 3</a>
    </li>
</ul>

@switch(tabId) 

    case 1:
        <Tab1Component />
        break;
    case 2:
        <Tab2Component />
        break;
    case 3:
        <Tab3Component />
        break;


@code 
    private int tabId = 1;

但这不起作用,因为当我切换标签时,OnInitializedAsync 每次都会被调用。

如果有一个 hidden blazor 属性会很有帮助,我可以像这样向标签正文添加一个属性:

<Tab1Component @hidden="tabId != 1" />

【问题讨论】:

【参考方案1】:

我找到的一个解决方案是创建一个Hidable 组件:

Hidable.razor.cs

public partial class Hidable

    [Parameter] public bool? hidden  get; set; 
    [Parameter] public bool? show  get; set; 
    protected override void OnParametersSet()
    
        if (hidden.HasValue && show.HasValue)
        
            throw new Exception($"Do not set BOTH nameof(hidden) and nameof(show)!");
        
    
    [Parameter] public RenderFragment ChildContent  get; set; 
    private string style
    
        get
        
            if (hidden.HasValue && !hidden.Value) return "";
            if (show.HasValue && show.Value) return "";
            return "display: none";
        
    

Hidable.razor

<div style="@style">@ChildContent</div>

使用示例

<Hidable hidden="@(tabId == 1)">
    <Tab1Component />
</Hidable>
<Hidable hidden="@(tabId == 2)">
    <Tab2Component />
</Hidable>
<Hidable hidden="@(tabId == 3)">
    <Tab3Component />
</Hidable>

【讨论】:

谢谢亨克。我修好了。【参考方案2】:
标签正文在重新出现时不应被初始化两次。 (它不应运行两次 OnInitializedAsync)。

Blazor 确定何时初始化组件,您的问题实际上是“如何维护状态”。有很多方法可以做到这一点。

但我可以看到,带有用户输入的复杂控件很难恢复。

如果有隐藏的 blazor 属性会有帮助

你可以做一个。您的 Tab1-3Component 类可以公开一个布尔值并使用 CSS 在外部标记上设置 display=none。我想你不能条件渲染,因为那会再次失去状态。

switch 语句将被替换为

<Tab1Component Visible=(tabId==1) />
<Tab2Component Visible=(tabId==2) />
<Tab3Component Visible=(tabId==3) />

【讨论】:

以上是关于带有 OnInitializedAsync 的选项卡?的主要内容,如果未能解决你的问题,请参考以下文章

动态创建带有闪亮绘图的选项卡,而无需重新创建现有选项卡

Python argparse - 带有 dict 选项的选项

带有 UINavigationController 作为选项卡的 UITabViewController

带有片段的 ActionBar 选项卡旋转

带有动态选项卡的角度路由

带有每个选项结果计数的搜索菜单