所以,我有一个包含网格的页面
搜索页面.razor
<FiGrid @ref="Grid"
<Columns>
@Columns
</Columns>
<EditFormTemplate Context="contextEntity">
@EditFormTemplate(contextEntity)
</EditFormTemplate>
</FiGrid>
@code{
protected RenderFragment Columns { get; set; }
protected RenderFragment<object> EditFormTemplate { get; set; }
}
此页面有一个渲染片段来呈现列,还有一个用于在必要时呈现编辑表单
我从这个搜索页面继承来自定义这 2 个道具:
CustomSearchPage.razor
@inherits SearchPage
@{
base.BuildRenderTree(__builder);
}
@code {
private static RenderFragment _customColumns = __builder =>
{
<CustomColumn FieldName="@nameof(Factory.Id)" Width="75px"/>
<CustomColumn FieldName="@nameof(Factory.BusinessName)"/>
<CustomColumn FieldName="@nameof(Factory.Address)"/>
};
private static RenderFragment<object> _customEditFormTemplate = editModel => __builder =>
{
<CustomEditForm Entity="editModel"/>;
};
protected override void OnInitialized()
{
Columns = _customColumns;
EditFormTemplate = _customEditFormTemplate;
base.OnInitialized();
}
}
但它在控制台上给了我这个错误:
由于对象的当前状态,操作无效。
也许我使用了错误的方法,在这种情况下,我应该如何完成同样的事情?
我需要能够从页面继承,并向页面传递采用模板上下文的自定义编辑表单
基本上我想将模板的上下文传递给通过代码创建的渲染片段
您收到错误是因为您无法按照设想的方式构建组件继承。 您不能像这样手动调用BuildRenderTree
:
base.BuildRenderTree(__builder);
因为您没有对渲染器的RenderTreeBuilder
的引用。
RenderFragment
是定义为以下内容的委托:
public delegate void RenderFragment(RenderTreeBuilder builder);
它由调用它的Renderer
运行,并在渲染器的RenderTreeBuilder
实例中传递。
所有 Razor 页面都预编译为 C# 类。 所以这个简单的组件DisplayDiv.razor
:
<h3>@Header</h3>
@code {
[Parameter] public string Header { get; set; } = "Hello Blazor";
}
由 Razor 处理器预编译为如下所示的内容:
public class DisplayDiv : ComponentBase
{
[Parameter] public string Header { get; set; } = "Hello Blazor";
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(0, "h3");
builder.AddContent(1, this.Header);
builder.CloseElement();
}
}
BuildRenderTree
被添加到ComponentBase
的基本渲染片段中,当调用渲染组件时,StateHasChanged
传递给渲染器。
private readonly RenderFragment _renderFragment;
public ComponentBase()
{
_renderFragment = builder =>
{
_hasPendingQueuedRender = false;
_hasNeverRendered = false;
BuildRenderTree(builder);
};
}
您正在尝试定义BuildRenderTree
的多个副本,这在剃刀页面设置中无法完成。 由 Razor 预编译器生成的子BuildRenderTree
方法将覆盖父方法。
您的SearchPage
是随后在页面中使用的组件
<SearchPage>
<Columns>
<CustomColumn FieldName="@nameof(Factory.Id)" Width="75px"/>
<CustomColumn FieldName="@nameof(Factory.BusinessName)"/>
<CustomColumn FieldName="@nameof(Factory.Address)"/>
</Columns>
<EditFormTemplate>
<CustomEditForm Entity="editModel"/>
</EditFormTemplate>
</SearchPage>
可以在组件中进行继承,但父组件必须是类,而不是 Razor 组件,并直接在代码中生成任何标记。