如何在两个同级 Blazor 组件之间进行通信? [英] How do I communicate between two sibling Blazor components?

查看:19
本文介绍了如何在两个同级 Blazor 组件之间进行通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I have a Blazor page with two components. One component has a button which generates a random number when clicked. The other component has a text area which should display the generated random number.

<h1>Parent Page</h1>

<ProvideNumberComponent />

<DisplayNumberComponent  />

@code {
}

<h3>Provides Number</h3>

<button class="btn btn-primary" @onclick="CalculateNumber">Provide Number</button>

@code {
    private void CalculateNumber(MouseEventArgs e)
    {
        Random rnd = new Random();
        Int32 nextNumber = rnd.Next();
    }

}

<h3>Displays number</h3>

<textarea cols="9" rows="1" readonly style="font-family:monospace;" />

@code {

}

What is the cleanest way to get the number from the calculate sibling component to appear in the display sibling component?

A problem with my code is that the Random object is instantiated on every button click, instead of once on initialization. Is this best addressed by placing the Random object in a singleton service class, and injecting that into the calculate component?

解决方案

The best solution, to my mind, is to create a service which implements the state pattern and the notifier pattern. The following code describes how communication between two sibling can be done through an intermediary

NotifierService.cs

public class NotifierService
{
    public NotifierService()
    {

    }

    int rnd;
    public int RandomNumber
    {
        get => rnd;
        set
        {
            if (rnd != value)
            {
                rnd= value;

                if (Notify != null)
                {
                    Notify?.Invoke();
                }
            }
        }
     }
     public event Func<Task> Notify;
 }

Add this: services.AddScoped<NotifierService>();

ProvideNumberComponent.razor

 @inject NotifierService Notifier
 @implements IDisposable

<h3>Provides Number</h3>

 <button class="btn btn-primary" @onclick="CalculateNumber">Provide 
                                                    Number</button>

 @code 
 {
    private void CalculateNumber(MouseEventArgs e)
   {
      Random rnd = new Random();
      Int32 nextNumber = rnd.Next();

      Notifier.RandomNumber = nextNumber; 
   }

   public async Task OnNotify()
   {
    await InvokeAsync(() =>
    {
        StateHasChanged();
    });
  }


 protected override void OnInitialized()
 {
    Notifier.Notify += OnNotify;
 }


 public void Dispose()
 {
    Notifier.Notify -= OnNotify;
 }

}

DisplayNumberComponent.cs

 @inject NotifierService Notifier
 @implements IDisposable

 <hr />
<h3>Displays number</h3>

<textarea cols="9" rows="1" readonly style="font-family:monospace;">
    @Notifier.RandomNumber
</textarea>

@code {

    public async Task OnNotify()
   {
    await InvokeAsync(() =>
    {
        StateHasChanged();
    });
  }


 protected override void OnInitialized()
 {
    Notifier.Notify += OnNotify;
 }


 public void Dispose()
 {
    Notifier.Notify -= OnNotify;
 }

 }

Of course you can inject and use the service in multiple components, as well as adding more features that the service can provide. Implementing communication by means of event handlers may be problematic, unless it is between a parent and its child...

Hope this works...

这篇关于如何在两个同级 Blazor 组件之间进行通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆