【问题标题】:Tabs with OnInitializedAsync?带有 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" />

【问题讨论】:

    标签: blazor blazor-server-side


    【解决方案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) />
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多