我有一个自定义按钮组件,如下所示。
<button class="btn btn-outline-primary" @onclick="OnClick"> @ButtonText</button>
@code {
[Parameter]
public string ButtonText { get; set; } = "Edit";
public virtual void OnClick()
{
ButtonText = ButtonText == "Edit" ? "Editing..." : "Edit";
}
}
当我点击按钮时,所有东西都正常工作,按钮文本也在变化。但当我点击另一个按钮时,我想更改按钮的文本。为此,我调用了按钮的onclick方法。但是,当我单击按钮时,即使调用了该方法,文本也不会更改。这是我的页面。
@page "/test"
<EditButton @ref="EditButton"></EditButton>
<button class="btn-primary" @onclick="ChangeButtonText">Change Button Text</button>
@code {
EditButton EditButton;
void ChangeButtonText()
{
EditButton.OnClick();
}
}
这部分是由于您的架构设计:ButtonComponent不应该管理编辑状态,它应该只显示它。
编辑按钮
<button class="btn btn-outline-primary" @onclick="Click"> @ButtonText</button>
@code {
// don't change [Parameter] properties inside this component,
// they are set by the Owner
[Parameter]
public bool IsEditing { get; set; }
[Parameter]
public EventCallback Click { get; set; }
public string ButtonText => IsEditing ? "Editing..." : "Edit";
}
测试页面
@page "/test"
<EditButton IsEditing="isEditing" Click="EditClick"></EditButton>
<button class="btn-primary" @onclick="ChangeButtonText">Change Button Text</button>
@code {
//EditButton EditButton;
bool isEditing = false;
void ChangeButtonText()
{
isEditing = false; // or !isEditing
}
void EditClick()
{
isEditing = ! isEditing;
}
}
您的代码不能正常工作,因为它缺少对StateHasChanged
方法的调用:
编辑按钮剃刀
<button class="btn btn-outline-primary" @onclick="OnClick"> @ButtonText</button>
@code {
[Parameter]
public string ButtonText { get; set; } = "Edit";
public void OnClick()
{
ButtonText = ButtonText == "Edit" ? "Editing..." : "Edit";
InvokeAsync(() => StateHasChanged());
}
}
注意,我添加了一个对StateHasChanged方法的调用,以便在组件状态更改后重新呈现组件。
InvokeAsync(() => StateHasChanged());
索引.razor
@page "/"
<EditButton @ref="EditButton"></EditButton>
<button class="btn-primary" @onclick="ChangeButtonText">Change Button Text</button>
@code {
EditButton EditButton;
void ChangeButtonText()
{
EditButton.OnClick();
}
}
总之:您所做的很好,但必须手动调用StateHasChaged方法。它不是由框架自动调用的。请注意,没有必要从处理UI事件(如"click"事件(的事件处理程序添加对StateHasChaged方法的调用。但在您的情况下,这是必要的,因为EditButton.OnClick事件处理程序不是UI事件处理程序。这就是代码中的only
问题。
重要事项:不应修改或更改组件参数属性的状态。应避免这种情况:
[Parameter]
public string ButtonText { get; set; } = "Edit";
除此之外:
ButtonText = ButtonText == "Edit" ? "Editing..." : "Edit";
组件参数属性应为自动属性:
[Parameter]
public string ButtonText { get; set; }
而且它们决不能在组件之外进行修改。读这个读这个。相反,您应该定义局部变量或从组件参数属性值分配的属性,您可以对其应用任何您想要的操作。
不遵守这一规则可能会在大型组件中产生不利的副作用,只有Steve Sanderson才能察觉到。
这个简单的解决方案怎么样。CCD_ 4保持不变。
@page "/"
<EditButton ButtonText="@this.editButtonText" ></EditButton>
<button class="btn btn-primary ml-3" @onclick="ChangeButtonText">Change Button Text</button>
@code {
string editButtonText = "Edit";
void ChangeButtonText()
{
editButtonText = editButtonText.Equals("Edit")
? "Editing"
: "Edit";
}
}
您不需要连接回调和引用。当您更改组件上ButtonText
的值并在父级上触发Blazor组件事件处理程序ChangeButtonText
时,Renderer会检测到对ButtonText
的更改,并通过调用SetParametersSetAsync
通知EditButton
。这将在EditButton
上引发一个渲染事件,并更新按钮文本。