Blazor组件需要修改父组件的值



我的Blazor应用程序中有以下两个组件:

组件1.剃须刀:

<CascadingValue Value=this>
<Component2/>
</CascadingValue>
<p>@DisplayedText</p>
@code {
public string DisplayedText = string.Empty;
}

组件2.剃须刀:

<button @onclick=@(e => { C1.DisplayedText = "testing"; })>Set DisplayedText</button>
@code {
[CascadingParameter]
public Component1 C1 { get; set; }
}

当我单击"Set DisplayedText"按钮时,Component1p元素中的文本应该更改为testing,但它没有。我该怎么解决这个问题?

@Merlin04,这是对级联值功能的滥用。通常,父零部件通过零部件参数与其子零部件进行通信。

您不能更新子代的级联值。

错误。。。

以下代码片段根据您的操作演示了一个更好的解决方案,尽管它不是最佳的,因为您的代码和我的代码也会从方法更新属性,而事实上,我们应该直接更改属性的值,而不是通过中介代码(这是一种方法(

组件2.剃须刀

<button @onclick="@(() => SetDisplayedText.InvokeAsync("testing"))">Set 
DisplayedText</button>
@code {
[Parameter]
public EventCallback<string> SetDisplayedText { get; set; }
}

组件1.剃须刀

<Component2 SetDisplayedText="@SetDisplayedText"/>
<p>@DisplayedText</p>
@code {
private string DisplayedText = string.Empty;
public void SetDisplayedText(string newText)
{
DisplayedText = newText;
}
}

请注意,调用StateHasChanged方法是不必要的,因为这是使用EventCallback"delegate"时获得的奖励

希望这能帮助。。。

Merlin04,下面的代码片段演示了如何做到这一点。请注意,这确实是一个非常简单的示例,但它显示了当需要在远程组件之间进行通信时应该如何进行编码。

这是代码,复制并运行它,如果您有更多问题,请不要犹豫。

消息服务.cs

public class MessageService
{
private string message;
public string Message
{
get => message;
set
{
if (message != value)
{
message = value;
if (Notify != null)
{
Notify?.Invoke();
}
}
}
}
public event Action Notify;
}

注意:该服务是普通类。。。它为其他对象提供服务,并且应该将它添加到Startup.ConfigureServices方法中的DI容器中,以使其可用于请求客户端。将此添加到ConfigureServices方法:

services.AddScoped<MessageService>();

注意:正如您所看到的,我定义了Action类型的事件委托,当用户在Component3中的文本框中键入文本时,它将从属性的set访问器调用。触发此委托会导致Components3输入的文本显示在Index组件中,该组件是Component2的父组件(请参阅下面的代码(。

索引.razor

@page "/"
@inject MessageService MessageService
@implements IDisposable
<p>I'm the parent of Component2. I've got a message from my grand child: 
@MessageService.Message</p>
<Component2 />
@code {
protected override void OnInitialized()
{
MessageService.Notify += OnNotify;
}
public void OnNotify()
{
InvokeAsync(() =>
{
StateHasChanged();
});
}
public void Dispose()
{
MessageService.Notify -= OnNotify;
}
}

请注意,我们直接绑定到MessageService.Message属性,但必须调用StateHasChanged方法来刷新文本的显示。

组件2.剃须刀

<h3>Component2: I'm the parent of component three</h3>
<Component3/>
@code {
}

组件3.剃须刀

@inject MessageService MessageService
<p>This is component3. Please type a message to my grand parent</p>
<input placeholder="Type a message to grandpa..." type="text" 
@bind="@MessageService.Message" @bind:event="oninput" />

请注意,在Component3中,我们将MessageService.Message绑定到一个文本框,每次按下键盘时都会进行绑定(输入事件与更改事件(。

仅此而已,希望这能有所帮助,并且不要犹豫问任何问题。

请参阅enet的答案,而不是以下内容

不能从子体更新级联值。

相反,在父级(Component1(中创建一个方法来设置值:

public void SetDisplayedText(string newText) {
DisplayedText = newText;
StateHasChanged();
}

然后,您可以在子代中调用它:

<button @onclick=@(e => { C1.SetDisplayedText("testing"); })>Set DisplayedText</button>

最新更新