Blazor CascadingParameter 始终为 null

Blazor CascadingParameter is always null

Blazor 新手,无法从我的 MainLayout.razor:

获取 CascadingParameter 来填充
@code
{
    private Toasts Toasts { get; set; }
}
        
<Toasts @ref="@Toasts" />
    
<CascadingValue Value="Toasts">
    @Body
</CascadingValue>

Index.razor页面:

[CascadingParameter]
public Toasts Toasts { get; set; }

public async Task PackageChanged(string value)
{
   Toasts.Something(value); //Toasts is null here
}

最后 Toasts.razor:

@code {

    private string Message { get; set; }

    public void Something(string message)
    {
        Message = message;
        StateHasChanged();
    }
}

@Message

下面这段代码令人沮丧,但我只想级联一个组件 (<Toasts />) 而不是整个布局:

<CascadingValue Value="@this">
    <Toasts @ref="@Toasts" />
    @Body
</CascadingValue>

然后索引:

[CascadingParameter]
public MainLayout Layout { get; set; }

 public async Task PackageChanged(string value)
 {
      Layout.Toasts.Something(value); //this behaves as expected
 }

MainLayout.razor 中的这条语句不起作用

<Toasts @ref="@Toasts" />

但是这个语句有效并且 index.razor 中的级联参数不为空

@code
{
    private Toasts Toasts= new();
}

似乎 Blazor 不允许将元素引用作为级联参数传递,但只允许对象和其他变量。我不了解您的要求的完整上下文,但您可以尝试将 Toasts 作为服务实施。

这段代码对我有用

MainLayout...部分代码

<div class="main">
        <div class="top-row px-4">
            <Toasts @ref="Toasts" />
        </div>

        @if (Toasts != null)
        {
            <CascadingValue Value="@Toasts">
                @Body
            </CascadingValue>
        }
 </div>

@code
{
    protected Toasts Toasts;

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            StateHasChanged();
        }
    }
 }

下面的解决方案,我们级联一个对 MainLayout 的引用,然后检索对 Toasts 组件的引用,比上面的更有效,因为它不需要 MainLayout 进行第二次渲染.

MainLayout...部分代码

<div class="main">
        <div class="top-row px-4">
            <Toasts @ref="Toasts" />
        </div>

         <CascadingValue Value="this">
            @Body
         </CascadingValue>     
 </div>

@code
{
    public Toasts Toasts { get; set; }
 } 

Index.razor

@page "/"

@code{
   
    [CascadingParameter]
    public MainLayout Layout { get; set; }
    
   
    protected override void OnInitialized()
    {
        // Reference the Toasts component's methods and properties
        // Note: You must not pass parameter values to the Toasts
        // component from here. You'll get a warning, or perhaps 
        // an error.
 
        Layout.Toasts.Something("Pass a message to the 
                                Something method");
    }

}