簡體   English   中英

如何將值從子組件(RenderFragment)傳遞到 C# Blazor 中的父頁面?

[英]How to pass value from Child component (RenderFragment) to Parent page in C# Blazor?

我有一個 Blazor 項目,它加載包含 razor 組件的 DLL 項目。 為了在客戶端渲染這些動態組件,我使用渲染樹構建器從動態組件創建一個RenderFragment並將其放置在頁面上以顯示該組件。 但是,我在創建渲染樹時找不到綁定值的方法。 通常,我可以使用下面的父子組件示例傳遞數據,但不確定在將動態組件轉換為RenderFragment時如何做。

父組件

@page "/ParentComponent"

<h1>Parent Component</h1>

<ChildComponent @bind-Password="_password" />

@code {
    private string _password;
 }

子組件

<h1>Child Component</h1>

Password:

<input @oninput="OnPasswordChanged"
       required
       type="@(_showPassword ? "text" : "password")"
       value="@Password" />

<button class="btn btn-primary" @onclick="ToggleShowPassword">
    Show password
</button>

@code {
    private bool _showPassword;

    [Parameter]
    public string Password { get; set; }

    [Parameter]
    public EventCallback<string> PasswordChanged { get; set; }

    private Task OnPasswordChanged(ChangeEventArgs e)
    {
        Password = e.Value.ToString();
        return PasswordChanged.InvokeAsync(Password);
    }
    private void ToggleShowPassword()
    {
        _showPassword = !_showPassword;
    }
}

RenderFragment的動態組件

下面的代碼顯示了我如何通過將組件轉換為RenderFragment在頁面上顯示該組件。 您知道如何在渲染樹構建器中綁定變量,以將數據從動態組件傳遞到父頁面嗎?

注意:這個動態組件@dynamicComponent與上面的子組件相同,我想要從中獲取密碼數據。

@page "/{ComponentName}"
@inject IComponentService ComponentService

@if (render)
{
    @dynamicComponent()
    
    @_password;
}
    
@code{
    private string _password;
    
    [Parameter]
    public string ComponentName { get; set; }
    bool render = false;
    
    protected override void OnInitialized()
    {
        render = true;
        base.OnInitialized();
    }
    
    RenderFragment dynamicComponent() => builder =>
    {
        RazorComponentModel component = ComponentService.GetComponentByPage(ComponentName);
        builder.OpenComponent(0, component.Component);
        for (int i = 0; i < component.Parameters.Count; i++)
        {
            var attribute = component.Parameters.ElementAt(i);
            builder.AddAttribute(i + 1, attribute.Key, attribute.Value);
        }
        builder.CloseComponent();
    };
}

讓我們先看看我的理解是否正確......您想創建一種組件渲染器,它獲取組件的名稱作為參數,並通過 IComponentService 獲取組件的Type ,然后渲染它。 我也猜想組件的Type可能是Type Child ,你想知道如何在 Index 頁面中渲染它,並獲取在 Child 組件中輸入的密碼,對吧? 下面的代碼描述了如何做到這一點,但是我當然不能使用 IComponentService 服務來發現組件的類型,而是假設類型是Child

復制並運行代碼片段。 測試它......它應該工作......

@page "/{ComponentName?}"

@using Microsoft.AspNetCore.Components.CompilerServices;

@if (render)
{
    @dynamicComponent
   
}

<p>Your password: @_password</p>
@code{
    private string _password;

    [Parameter]
    public string ComponentName { get; set; }

    bool render = false;

    protected override void OnInitialized()
    {
        render = true;
        base.OnInitialized();
    }

    RenderFragment dynamicComponent => builder =>
    {
        builder.OpenComponent(0, typeof(Child));
        builder.AddAttribute(1, "Password", _password);
        builder.AddAttribute(2, "PasswordChanged", 
            EventCallback.Factory.Create<string>(this, 
            RuntimeHelpers.CreateInferredEventCallback(this, __value => _password = __value, _password)));
        builder.CloseComponent();

    };
}

注意:您不應修改子組件中參數屬性的值。 Blazor 中的參數屬性是自動屬性,這意味着您可以訪問它們的值但不能更改它們。

此外,您不應該通過循環創建序列號。 序列號應該是硬編碼的。 谷歌搜索 Steve Anderson 的一篇文章中討論的這個主題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM