【问题标题】:Blazor Passing Data from Parent to ChildBlazor 将数据从父级传递给子级
【发布时间】:2020-09-22 03:30:53
【问题描述】:

我有一个取决于其父类的剃须刀页面和第二个子类,它有自己的类并从其父类接收数据,我的问题是第二次调用 api,数据没有传递给第二个孩子,当其父母更改其数据时,第二个孩子不会被渲染,但它在第一个渲染上工作并且正在传递数据。

Parent.razor

@inherits ParentBase;

<FirstChild/>
<SecondChild data="@data"/>

FirstChild.razor

@inherits ParentBase;

// call its parent method
<span  @onclick='(() => callApi())'/> 

ParentBase.cs

public class ParentBase : ComponentBase
{
   public Data data { get; set; }
   protected override async Task OnInitializedAsync()
   {
       data = await Services.GetData();
   }
   // call from a child
   public void callApi
   {
     data = await Services.GetData();
   }
}

SecondChild.razor

<Table data="@data"/>

SecondChildBase.cs

public class SecondChildBase : ComponentBase
{
   [Parameter]
   public Data data { get; set; }

   protected override void OnParametersSet()
   {
       // this is not getting called
       StateHasChanged();
       Console.WriteLine(data);
   }
}

【问题讨论】:

    标签: c# asp.net .net razor blazor


    【解决方案1】:

    仅仅因为Parent.razorFirstChild.razor继承自同一个类,并不意味着这两个类(public Data data { get; set; })的数据在更改时将具有相同的值。

    当你在FirstChild中调用callApi时,它会改变它自己的data,如果你想改变父级的data,你需要传递一个参数给FirstChild这将是一个函数在单击span 时调用,这将调用ParentcallApi

    FirstChild.razor

    <span @onclick="OnClick">Call Parent function</span>
    
    @code 
    {
        // Call this EventCallback when the span is clicked
        [Parameter]
        public EventCallback OnClick { get; set; }
    }
    

    Parent.razor

    @inherits ParentBase;
    
    @* Passing OnClick Parameter to call callApi*@
    <FirstChild OnClick="@callApi" />
    <SecondChild data="@data" />
    

    【讨论】:

    • 感谢您的快速响应,我继承父类以避免使用 EventCallback 的原因是因为我有很多来自不同子级的 api 调用,并且很难通过 EventCallback 特别如果孩子嵌套在另一个孩子中。
    • 对于这种情况,我有另一个孩子,它在第二个孩子里面,需要调用 api 并更改数据,最好的方法是什么?谢谢
    • @AhmedImam 如果您希望多个子组件访问该功能并且不想将参数传递给所有子组件,您可以使用CascadingValue 或创建看起来像“服务”的东西。如果您想了解更多信息,请阅读此article
    • +1 for cascadingparameter here..这是要走的路..我会给你子组件中“父”的实例,这样你就可以直接调用它
    【解决方案2】:

    我认为您可以尝试数据绑定而不是 CascadingParameter。

    文档在这里: https://docs.microsoft.com/en-us/aspnet/core/blazor/data-binding?view=aspnetcore-3.1

    特别是以下两个主题:

    • 使用组件参数的父子绑定
    • 使用链式绑定的子到父绑定

    示例:父组件

    <PasswordField @bind-Password="password" />
    
    @code {
        private string password;
    }
    

    示例:子组件

    <input @oninput="OnPasswordChanged" 
           required 
           type="@(showPassword ? "text" : "password")" 
           value="@Password" />
    
    @code {
        private bool showPassword;
        private string password;
        private string validationMessage;
    
        [Parameter]
        public string Password
        {
            get { return password ?? string.Empty; }
            set
            {
                if (password != value)
                {
                    if (value.Contains(' '))
                    {
                        validationMessage = "Spaces not allowed!";
                    }
                    else
                    {
                        password = value;
                        validationMessage = string.Empty;
                    }
                }
            }
        }
    
        [Parameter]
        public EventCallback<string> PasswordChanged { get; set; }
    
        private Task OnPasswordChanged(ChangeEventArgs e)
        {
            Password = e.Value.ToString();
    
            return PasswordChanged.InvokeAsync(Password);
            }
    
        }
    

    您的子组件需要提供一个 {Password}Changed,其中 {} 是您的参数。 这样,当孩子更新时,父母也会更新(以及所有其他绑定参数)

    【讨论】:

      【解决方案3】:

      只需在服务调用简单后将 StateHasChanged() 移动到基...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-01
        • 2020-09-11
        • 2011-09-07
        • 2021-06-29
        • 1970-01-01
        • 2018-03-09
        • 2016-11-14
        • 2023-03-13
        相关资源
        最近更新 更多