blazor 向模板化组件添加参数
blazor add parameters to templated component
我有一个 Blazor Popup,它采用模板来显示他的内容:
CustomPopup.razor
<Popup
@bind-Visible="@CreatePopupVisible"
HorizontalAlignment="HorizontalAlignment.Center"
VerticalAlignment="VerticalAlignment.Center"
ShowFooter="true"
HeaderText="@("Create" + Label)">
<BodyTemplate>
@EditForm
</BodyTemplate>
<FooterContentTemplate>
</FooterContentTemplate>
</Popup>
@code {
[Parameter]
public string? Label { get; set; }
[Parameter]
public RenderFragment EditForm { get; set; }
bool CreatePopupVisible { get; set; }
}
我向这个组件传递了一个带有 2 个按钮的 EditForm,它采用一个函数来处理取消选项:
CustomEditForm.razor
<EditForm Model="Entity" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="d-flex flex-column">
<InputNumber id="factory-id" class="mt-2 mb-2" @bind-Value="Entity.Id" />
<InputText id="factory-businessname" class="mt-2 mb-2" @bind-Value="Entity.BusinessName" />
<InputText id="factory-address" class="mt-2 mb-2" @bind-Value="Entity.Address" />
<div class="d-flex flex-row">
<button class="btn btn-primary mt-2 mb-2 flex-grow-1" type="submit">Modifica</button>
<button @onclick="HandleCancel" class="btn btn-secondary mt-2 mb-2 flex-grow-1" type="submit">Annulla</button>
</div>
</div>
</EditForm>
@code {
[Parameter]
public Action HandleCancel { get; set; }
[Parameter]
public Factory Entity { get; set; }
private void HandleValidSubmit()
{
Logger.LogInformation("HandleValidSubmit called");
}
}
如果我像这样正常使用 EditForm:
SomeFile.razor
<CustomEditForm HandleCancel="()=>{}">
一切都很好,但是当我在模板化组件中使用它时,如何从 CustomPupup.razor 文件中向他传递一个函数?
我需要传递一个函数来在有人点击取消按钮时将 CreatePopupVisible 设置为 false
提前求助!
编辑
感谢您的帮助,但我认为我提供的信息不足,无法获得正确答案,我的错
所以,我希望能够正常调用 CustomEditForm 并传递父定义的函数来管理 HandleCancel,如下所示:
MainPage.razor
@page ...
<Grid @ref="Grid">
//the grid has a method that closes this CustomEditForm
<Template>
<CustomEditForm HandleCancel="() => Grid.CancelRowEdit()"/>
</Template>
</Grid>
但我也想使用自己内部定义的函数关闭弹出窗口,如下所示:
AnotherPage.razor
<CustomPopup>
<EditForm>
<CustomEditForm Entity="new Factory()"/>
</EditForm>
</CustomPopup>
在这种情况下,编辑表单应通过调用 CustomPopup 定义的方法来处理取消
由于您的问题中没有足够的代码作为答案的基础,我将使用一个非常简单的组件来演示您如何可以做您想做的事情。
这是我的“PopUp”模拟器。
@if (this.Visible)
{
<h3>PopUp</h3>
@this.ChildContent
}
@code {
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public bool Visible { get; set; }
}
然后是我的 CustomPopUp。请注意,我正在级联 this
并且有一个 public Close
方法。
<PopUp Visible="this.CreatePopupVisible">
<CascadingValue Value=this>
@this.ChildContent
</CascadingValue>
</PopUp>
@code {
[Parameter] public RenderFragment? ChildContent { get; set; }
bool CreatePopupVisible { get; set; }
public void Show()
{
this.CreatePopupVisible = true;
}
public void Close()
{
this.CreatePopupVisible = false;
this.StateHasChanged();
}
}
接下来是我的 EditForm。请注意,我捕获了 CustomMyPopUp
的 Cascaded 实例。我的 Cancel 现在检查我们是否有级联值(我们在 PopUp 上下文中),如果有,则在弹出窗口上调用 Close
。它还会检查 HandleCancel
上是否有已注册的委托,只有在有时才调用它。
<div class="m-2 p-5 bg-light">
<h3>EditForm</h3>
<div class="p-2 m-2">
<button class="btn btn-danger" @onclick="this.Cancel">Cancel</button>
</div>
</div>
@code {
[CascadingParameter] private CustomPopUp? myPopUp { get; set; }
[Parameter] public EventCallback<bool> HandleCancel { get; set; }
public async Task Cancel()
{
if (this.myPopUp is not null)
myPopUp.Close();
if (this.HandleCancel.HasDelegate)
await HandleCancel.InvokeAsync();
}
}
我的页面终于要测试了:
@page "/PopUp"
<h3>CascadePage</h3>
<CustomPopUp @ref=this.myPopUp>
<MyEditForm />
</CustomPopUp>
<div class="p-2 m-2">
<button class="btn btn-primary" @onclick="this.Show">Show</button>
</div>
@code {
private CustomPopUp? myPopUp;
public void Show()
=> this.myPopUp?.Show();
}
听起来您只是想将对内部方法的引用传递给 RenderFragment
,您可以使用 RenderFragment<Action>
来做到这一点 - 因为 HandleCancel
期望 Action
它可以 invoke
:
<Popup
@bind-Visible="@CreatePopupVisible"
HorizontalAlignment="HorizontalAlignment.Center"
VerticalAlignment="VerticalAlignment.Center"
ShowFooter="true"
HeaderText="@("Create" + Label)">
<BodyTemplate>
@EditForm(ClosePopup)
</BodyTemplate>
<FooterContentTemplate>
</FooterContentTemplate>
</Popup>
@code {
[Parameter]
public string? Label { get; set; }
[Parameter]
public RenderFragment<Action> EditForm { get; set; }
bool CreatePopupVisible { get; set; }
void ClosePopup()
{
CreatePopupVisible = false;
// Because this method will be called by some external code
// You should tell this component to render:
InvokeAsync(StateHasChanged);
}
}
要使用它,标记可以引用 EditForm
RenderFragment
的 context
,这是一个 Action
<CustomPopup>
<EditForm>
<CustomEditForm Entity="new Factory()" HandleCancel=@context/>
</EditForm>
</CustomPopup>
我有一个 Blazor Popup,它采用模板来显示他的内容:
CustomPopup.razor
<Popup
@bind-Visible="@CreatePopupVisible"
HorizontalAlignment="HorizontalAlignment.Center"
VerticalAlignment="VerticalAlignment.Center"
ShowFooter="true"
HeaderText="@("Create" + Label)">
<BodyTemplate>
@EditForm
</BodyTemplate>
<FooterContentTemplate>
</FooterContentTemplate>
</Popup>
@code {
[Parameter]
public string? Label { get; set; }
[Parameter]
public RenderFragment EditForm { get; set; }
bool CreatePopupVisible { get; set; }
}
我向这个组件传递了一个带有 2 个按钮的 EditForm,它采用一个函数来处理取消选项:
CustomEditForm.razor
<EditForm Model="Entity" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="d-flex flex-column">
<InputNumber id="factory-id" class="mt-2 mb-2" @bind-Value="Entity.Id" />
<InputText id="factory-businessname" class="mt-2 mb-2" @bind-Value="Entity.BusinessName" />
<InputText id="factory-address" class="mt-2 mb-2" @bind-Value="Entity.Address" />
<div class="d-flex flex-row">
<button class="btn btn-primary mt-2 mb-2 flex-grow-1" type="submit">Modifica</button>
<button @onclick="HandleCancel" class="btn btn-secondary mt-2 mb-2 flex-grow-1" type="submit">Annulla</button>
</div>
</div>
</EditForm>
@code {
[Parameter]
public Action HandleCancel { get; set; }
[Parameter]
public Factory Entity { get; set; }
private void HandleValidSubmit()
{
Logger.LogInformation("HandleValidSubmit called");
}
}
如果我像这样正常使用 EditForm:
SomeFile.razor
<CustomEditForm HandleCancel="()=>{}">
一切都很好,但是当我在模板化组件中使用它时,如何从 CustomPupup.razor 文件中向他传递一个函数?
我需要传递一个函数来在有人点击取消按钮时将 CreatePopupVisible 设置为 false
提前求助!
编辑
感谢您的帮助,但我认为我提供的信息不足,无法获得正确答案,我的错
所以,我希望能够正常调用 CustomEditForm 并传递父定义的函数来管理 HandleCancel,如下所示:
MainPage.razor
@page ...
<Grid @ref="Grid">
//the grid has a method that closes this CustomEditForm
<Template>
<CustomEditForm HandleCancel="() => Grid.CancelRowEdit()"/>
</Template>
</Grid>
但我也想使用自己内部定义的函数关闭弹出窗口,如下所示:
AnotherPage.razor
<CustomPopup>
<EditForm>
<CustomEditForm Entity="new Factory()"/>
</EditForm>
</CustomPopup>
在这种情况下,编辑表单应通过调用 CustomPopup 定义的方法来处理取消
由于您的问题中没有足够的代码作为答案的基础,我将使用一个非常简单的组件来演示您如何可以做您想做的事情。
这是我的“PopUp”模拟器。
@if (this.Visible)
{
<h3>PopUp</h3>
@this.ChildContent
}
@code {
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public bool Visible { get; set; }
}
然后是我的 CustomPopUp。请注意,我正在级联 this
并且有一个 public Close
方法。
<PopUp Visible="this.CreatePopupVisible">
<CascadingValue Value=this>
@this.ChildContent
</CascadingValue>
</PopUp>
@code {
[Parameter] public RenderFragment? ChildContent { get; set; }
bool CreatePopupVisible { get; set; }
public void Show()
{
this.CreatePopupVisible = true;
}
public void Close()
{
this.CreatePopupVisible = false;
this.StateHasChanged();
}
}
接下来是我的 EditForm。请注意,我捕获了 CustomMyPopUp
的 Cascaded 实例。我的 Cancel 现在检查我们是否有级联值(我们在 PopUp 上下文中),如果有,则在弹出窗口上调用 Close
。它还会检查 HandleCancel
上是否有已注册的委托,只有在有时才调用它。
<div class="m-2 p-5 bg-light">
<h3>EditForm</h3>
<div class="p-2 m-2">
<button class="btn btn-danger" @onclick="this.Cancel">Cancel</button>
</div>
</div>
@code {
[CascadingParameter] private CustomPopUp? myPopUp { get; set; }
[Parameter] public EventCallback<bool> HandleCancel { get; set; }
public async Task Cancel()
{
if (this.myPopUp is not null)
myPopUp.Close();
if (this.HandleCancel.HasDelegate)
await HandleCancel.InvokeAsync();
}
}
我的页面终于要测试了:
@page "/PopUp"
<h3>CascadePage</h3>
<CustomPopUp @ref=this.myPopUp>
<MyEditForm />
</CustomPopUp>
<div class="p-2 m-2">
<button class="btn btn-primary" @onclick="this.Show">Show</button>
</div>
@code {
private CustomPopUp? myPopUp;
public void Show()
=> this.myPopUp?.Show();
}
听起来您只是想将对内部方法的引用传递给 RenderFragment
,您可以使用 RenderFragment<Action>
来做到这一点 - 因为 HandleCancel
期望 Action
它可以 invoke
:
<Popup
@bind-Visible="@CreatePopupVisible"
HorizontalAlignment="HorizontalAlignment.Center"
VerticalAlignment="VerticalAlignment.Center"
ShowFooter="true"
HeaderText="@("Create" + Label)">
<BodyTemplate>
@EditForm(ClosePopup)
</BodyTemplate>
<FooterContentTemplate>
</FooterContentTemplate>
</Popup>
@code {
[Parameter]
public string? Label { get; set; }
[Parameter]
public RenderFragment<Action> EditForm { get; set; }
bool CreatePopupVisible { get; set; }
void ClosePopup()
{
CreatePopupVisible = false;
// Because this method will be called by some external code
// You should tell this component to render:
InvokeAsync(StateHasChanged);
}
}
要使用它,标记可以引用 EditForm
RenderFragment
的 context
,这是一个 Action
<CustomPopup>
<EditForm>
<CustomEditForm Entity="new Factory()" HandleCancel=@context/>
</EditForm>
</CustomPopup>