我的 Blazor 应用程序中有这两个组件:
组件1.剃须刀:
<CascadingValue Value=this>
<Component2/>
</CascadingValue>
<p>@DisplayedText</p>
@code {
public string DisplayedText = string.Empty;
}
Run Code Online (Sandbox Code Playgroud)
组件2.剃刀:
<button @onclick=@(e => { C1.DisplayedText = "testing"; })>Set DisplayedText</button>
@code {
[CascadingParameter]
public Component1 C1 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
p当我单击“设置显示文本”按钮时,元素中的文本Component1应更改为testing,但事实并非如此。我怎样才能解决这个问题?
Isa*_*aac 10
@Merlin04,这是对级联值功能的滥用和误用。通常,父组件通过组件参数与其子组件进行通信。
您无法从后代更新级联值。
错误的...
下面的代码片段展示了一个更好的解决方案,根据您所做的,尽管它不是最佳的,因为您的代码和我的代码也从方法更新属性,而事实上,我们应该直接更改属性的值,而不是通过中介代码(即方法)
<button @onclick="@(() => SetDisplayedText.InvokeAsync("testing"))">Set
DisplayedText</button>
@code {
[Parameter]
public EventCallback<string> SetDisplayedText { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
<Component2 SetDisplayedText="@SetDisplayedText"/>
<p>@DisplayedText</p>
@code {
private string DisplayedText = string.Empty;
public void SetDisplayedText(string newText)
{
DisplayedText = newText;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,调用 StateHasChanged 方法不是必需的,因为这是使用 EventCallback“委托”时获得的好处
希望这可以帮助...
Merlin04,以下代码片段演示了如何做到这一点。请注意,这实际上是一个非常简单的示例,但它展示了当远程组件之间需要通信时应如何编码。
这是代码,复制并运行它,如果您有更多问题,请随时询问。
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;
}
Run Code Online (Sandbox Code Playgroud)
注意:服务是一个普通的类...它为其他对象提供服务,应该在 Startup.ConfigureServices 方法中将其添加到 DI 容器中,以使其可供请求客户端使用。添加以下内容:到ConfigureServices方法:
services.AddScoped<MessageService>();
Run Code Online (Sandbox Code Playgroud)
注意:正如您所看到的,我定义了一个 Action 类型的事件委托,当用户在 Component3 中的文本框中键入文本时,该事件委托从属性的 set 访问器中调用。触发此委托会导致 Components3 输入的文本显示在作为 Component2 父级的 Index 组件中(请参见下面的代码)。
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们直接绑定到 MessageService.Message 属性,但必须调用 StateHasChanged 方法来刷新文本的显示。
<h3>Component2: I'm the parent of component three</h3>
<Component3/>
@code {
}
Run Code Online (Sandbox Code Playgroud)
@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" />
Run Code Online (Sandbox Code Playgroud)
请注意,在 Component3 中,我们将 MessageService.Message 绑定到文本框,并且每次按下键盘时都会发生绑定(输入事件与更改事件)。
以上就是全部内容,希望对您有所帮助,如有任何问题,请随时提出。