【问题标题】:Blazor - How to manager @ref for initial invisible part of a componentBlazor - 如何为组件的初始不可见部分管理 @ref
【发布时间】:2022-01-14 23:37:30
【问题描述】:

我有一个 Blazor 组件,它由一个包含在 @if 指令 (IsVisible) 中的 div 组成。 div 有一个@ref。渲染组件时,IsVisible 为 false。我的组件有一个方法 (Show()) 将 IsVisible 设置为 true 并使用对 div 的引用。但引用始终为 null(没有 Context 也没有 Id)。

@if (IsVisible)
{
  <div @ref="MyRef">Bla bla bla</div>
}

@code {
  bool IsVisible = false;
  ElementReference MyRef;
  public void Show()
  {
    IsVisible = true;
    StateHasChanged();
    // here, MyRef has no Context and no Id
  }
}

【问题讨论】:

    标签: components blazor


    【解决方案1】:

    经典组件误解的一个例子:StateHasChanged 重新渲染组件。不,它将渲染事件排队到渲染器的队列中。在您的代码中,直到 Show 结束时才会发生这种情况 - 它是一个同步的代码块,因此在渲染器获得任何线程时间之前运行完成。您正在检查 MyRef 是否存在。

    你需要修改Show

        public async Task Show()
        {
            IsVisible = true;
            StateHasChanged();
            // Yields and lets the Renderer service it's queue
            await Task.Yield();
            // or await Task.Delay(1);
            // now we exist
            var x = MyRef;
      }
    

    【讨论】:

    • 您实际上无法确定 MyRef 是否会在 Yield() 期间设置 - 这取决于它的调用方式和其他情况。 (顺便说一下,不是我的 dv)。
    • @HenkHolterman。我打算用DivComponent 控制显示和隐藏的组件来回答这个问题,但我决定不直接回答这个问题。是的,我同意您可以使用可能影响服务队列的渲染器的代码加载 Show。
    【解决方案2】:

    你可以用 CSS 隐藏它:

    @if (true)
    {
      <div hidden="@(!IsVisible)" @ref="MyRef">Bla bla bla</div>
    }
    

    当然你可以删除@if (true)

    这样元素总是存在的,并且 MyRef 被尽快设置,在 OnAfterRender 中。

    当您在 OnInitializeAsync 中需要 MyRef 时,您仍然需要 Task.Yield() 形成 MrC 的答案。

    但是当你想绝对确定你有引用时,你将构建你的逻辑,以便在 OnAfterRender() 事件中或之后调用 Show()。

    【讨论】:

      猜你喜欢
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      • 2023-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      相关资源
      最近更新 更多