我具有在父级组件中动态创建的各种子级组件。
RenderFragment CreateChildComponent(long selectedcar) => builder =>
{
builder.OpenComponent(0, typeof(ChildComponent));
builder.AddAttribute(1, "Data", GetData(selecteccar));
builder.CloseComponent();
};
我有传递到这些子组件的数据列表。这些数据在父组件上定期更新。
我想在父组件中更新这些列表时更新子组件数据吗?
假设您使用的是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();
}
}
首先,我建议您将子组件嵌入其父组件中,而不要使用RenderFragment委托和RenderTreeBuilder。这非常复杂,需要Blazor的高级知识和易于设计微妙错误的能力。当您使用Razor语法编写组件时,编译器会进行繁重的工作,通常,编码会容易得多。
但是,您在代码中需要的是一种将Component参数传递给子组件的方法,这些参数应绑定到父组件中已更改的值。下面的代码应该可以解决问题。这不是完整的解决方案,而是可以从中得出设计的一些东西。如果您有问题,请不要犹豫,因为我不会解释大多数代码,这是简单明了的。]
@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);
}
}
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; }
}
<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; }
}