定期更改父组件中的数据后,是否可以更新子组件数据?

问题描述 投票:0回答:1

我具有在父级组件中动态创建的各种子级组件。

RenderFragment CreateChildComponent(long selectedcar) => builder =>
{
    builder.OpenComponent(0, typeof(ChildComponent));
    builder.AddAttribute(1, "Data", GetData(selecteccar));
    builder.CloseComponent();
};

我有传递到这些子组件的数据列表。这些数据在父组件上定期更新。

我想在父组件中更新这些列表时更新子组件数据吗?

blazor blazor-server-side
1个回答
0
投票

假设您使用的是this article中描述的那种情况:用您传递给CreateChildComponent方法的数据做一个属性,然后调用StateHasChanged()。像这样:

@page "/BuiltContent"

<h1>Build a component</h1>

@CustomRender

@code {
   private RenderFragment CustomRender { get; set; }
   public long selectedcar;

   RenderFragment CreateChildComponent() => builder =>
   {
       builder.OpenComponent(0, typeof(ChildComponent));
       builder.AddAttribute(1, "Data", GetData(selectedcar));
       builder.CloseComponent();
   };}

   void SomeInitMethod() {
       childFragment = CreateChildComponent();
   }

   void MyUpdateMethod() {
      // "list gets updated in parent component..."
      this.selectedcar = ...;
      StateHasChanged(); 
   }
}

0
投票

首先,我建议您将子组件嵌入其父组件中,而不要使用RenderFragment委托和RenderTreeBuilder。这非常复杂,需要Blazor的高级知识和易于设计微妙错误的能力。当您使用Razor语法编写组件时,编译器会进行繁重的工作,通常,编码会容易得多。

但是,您在代码中需要的是一种将Component参数传递给子组件的方法,这些参数应绑定到父组件中已更改的值。下面的代码应该可以解决问题。这不是完整的解决方案,而是可以从中得出设计的一些东西。如果您有问题,请不要犹豫,因为我不会解释大多数代码,这是简单明了的。]

ParentComponent.razor
@page "/ParentComponent"

<h1>Parent Component</h1>

@CustomRender

<button type="button" @onclick="RenderComponent">
    Create a child component
</button>


<button class="btn btn-primary" @onclick="UpdateTheCar">
    Change Car's color'
</button>


@code {

        public void UpdateTheCar()
        {
            SelectedCar.Color = "Red";

        }

    private RenderFragment CustomRender { get; set; }


    public Car SelectedCar { get; set; } = CarList.ElementAt(0);

    public static List<Car> CarList { get; set; } = new List<Car>() 
    {
        new Car(100, 2019, "Blue"), 
        new Car(101, 2019, "Soft Blue"),
        new Car(102, 2019, "Alice Blue")
    };

    private RenderFragment CreateChildComponent(long selectedcar) => builder =>
    {
        SelectCar( selectedcar);

        builder.OpenComponent(0, typeof(ChildComponent));
        // builder.AddAttribute(1, "Data", GetData(selectedcar));
        builder.AddAttribute(1, "Data", SelectedCar);
        builder.AddAttribute(2, "DataChanged", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<Microsoft.AspNetCore.Components.EventCallback<Car>>(Microsoft.AspNetCore.Components.EventCallback.Factory.Create<Car>(this, Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.CreateInferredEventCallback(this, __value => SelectedCar = __value, SelectedCar))));

        builder.CloseComponent();
    };

    private void  SelectCar(long selectedcar)
    {

        SelectedCar = CarList.Where(car => car.ID == selectedcar).First();

    }


    private void RenderComponent()
    {
        long selectedcar = 101;

        CustomRender = CreateChildComponent(selectedcar);
    }

}

Car.cs(应在共享文件夹中定义)
public class Car
    {

        public Car(long id, int yearofmanufacture, string color)

        {
            YearOfManufacture = yearofmanufacture;
            Color = color;
            ID = id;

        }

        public int YearOfManufacture { get; set; }
        public string Color { get; set; }
        public long ID { get; set; }
    }

ChildComponent.razor
<h2>Child Component</h2>

<p>SelecteCar: @Data.ID</p>
<p>YearOfManufacture: @Data.YearOfManufacture</p>
<p>Color: @Data.Color</p>

@code {
     [Parameter]
     public Car Data { get; set; }

    [Parameter]
    public EventCallback<Car> DataChanged { get; set; }
}

© www.soinside.com 2019 - 2024. All rights reserved.