当你使用
<PetDog @ref="dog" />
@code {
PetDog dog;
void ShowPetDetails()
{
dog.ToggleDisplay();
}
}
您实际上创建了对 PetDog 组件的引用,然后尝试在您没有引用的对象(PetTemplate 的实例)上调用派生方法 dog.ToggleDisplay()。为了使其工作,您必须获取对父组件 (PetTemplate) 的引用,并将其提供给派生组件 (PetDog),如下所示:
宠物模板.razor
<div class="mt-3">
<button @onclick="ToggleDisplay">Show Details (Inside)</button>
<h3>Pet Name: @Name</h3>
<div style="display:@display">
@ChildContent
</div>
</div>
@code {
string display = "none";
string val;
[Parameter]
public string Name { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
public void ToggleDisplay()
{
display = display == "none" ? "block" : "none";
InvokeAsync(() => StateHasChanged());
}
}
宠物狗剃须刀
@inherits PetTemplate
<PetTemplate @ref="petTemplate" Name="Dog">
<div>Someone's best friend!</div>
</PetTemplate>
@code
{
PetTemplate petTemplate;
public PetTemplate PetTemplateProp { get; set; }
protected override void OnAfterRender(bool firstRender)
{
if(firstRender)
{
PetTemplateProp = petTemplate;
}
base.OnAfterRender(firstRender);
}
}
索引.razor
@page "/"
<button @onclick="ShowPetDetails">Show Details (Outside)</button>
<PetDog @ref="dog" />
@code {
PetDog dog;
void ShowPetDetails()
{
dog.PetTemplateProp.ToggleDisplay();
}
}
注意:虽然 Razor 组件是 C# 类,但不能将它们视为普通类。他们的行为不同。例如,您不能在组件之外定义变量实例,并设置其参数等。充其量,您可以捕获对组件的引用以及调用组件实例上的公共方法,就像在当前示例中所做的那样。简而言之,组件对象不同于普通类。
同样重要的是要记住,每个组件都是一个独立的岛,可以独立于其父级和子级进行渲染。
但只是想知道如何从外部更改组件参数值,继承/使用模板。我尝试了文档中的方法或找到的资源,但不适用于我的情况
您不应该(这是一个警告)并且可能不能(现在可能是一个错误)在组件之外更改组件参数的值。例如,您不能捕获对组件的引用并为其参数属性赋值:
<PetTemplate @ref="petTemplate">
<div>Someone's best friend!</div>
</PetTemplate>
PetTemplate petTemplate;
这是不允许的:petTemplate.Name="Dog"
因为这是在其组件之外更改参数。你只能这样做:
<PetTemplate Name="Dog">
<div>Someone's best friend!</div>
</PetTemplate>
此外,不推荐从组件本身修改参数属性(目前您应该收到警告,至少 Steve Sanderson 向 Blazor 团队建议这样做)。为了清楚起见,您不应该从 PetTemplate 组件中修改参数属性 Name。参数属性应该是自动属性;也就是说,有一个像这样的 get 和 set 访问器:[Parameter] public string Name { get; set; }
而且你不应该像这样使用它:
private string name;
[Parameter]
public string Name
{
get => name;
set
{
if (name != value)
{
name = value;
// Code to a method or whatever to do something
}
}
}
这已被弃用,因为它可能有副作用。组件参数应视为 DTO,不应修改。如果您希望对参数值进行一些操作,请将其复制到局部变量中,然后执行您的操作。