• Blazor 组件通讯


      Blazor 组件通讯示例,包含联级传参、双向绑定、服务传参 3 种方式。

    Son.razor

     1 @using BlazorApp.Shared.Services;
     2 <div style="border:inherit;margin:inherit;background-color:ivory;">
     3     <h3>Son---@Value<input class="btn btn-info" type="button" value="自身+1,同时Self组件值+1" @onclick="ChangeValue" /></h3>
     4 
     5     <input type="text" @bind-value="@sunValue" />
     6     <input class="btn btn-info" type="button" value="控制Grand组件显示值" @onclick="ChangeGrandValue" />
     7 
     8     <h6>来自Parent组件 @ParentValue</h6>
     9     <input type="text" name="name" @bind-value="@Ceshi" />
    10     <button @onclick="@Henfgu">给邻居发消息</button>
    11 </div>
    12 @code {
    13     [Parameter]
    14     public int? Value { get; set; } = 0;
    15 
    16     public string? Ceshi { get; set; }
    17     [Inject]
    18     public CommunicationToString? communicationToString { get; set; }
    19 
    20     private async Task ChangeValue()
    21     {
    22         Value++;
    23         if (OnValueChanged.HasDelegate)
    24         {
    25             await OnValueChanged.InvokeAsync(Value);
    26         }
    27     }
    28 
    29     public string? sunValue { get; set; } = "Sun";
    30 
    31     /// <summary>
    32     /// 获取Name为GrandValue的Grand组件
    33     /// </summary>
    34     [CascadingParameter(Name = "GrandValue")]
    35     Grand? grand { get; set; }
    36 
    37     public async Task ChangeGrandValue()
    38     {
    39         await InvokeAsync(grand?.State_HasChanged(() => { grand.SetValue($"来自Sun组件 {sunValue}"); })!);
    40     }
    41 
    42     public async Task Henfgu()
    43     {
    44         if (communicationToString != null)
    45             communicationToString.Callback(Ceshi ?? "");
    46 
    47         await Task.CompletedTask;
    48     }
    49 
    50     [CascadingParameter(Name = "ParentValue")]
    51     string? ParentValue { get; set; }
    52 
    53     [Parameter]
    54     public EventCallback<int?> OnValueChanged { get; set; }
    55 }

    Self.razor

     1 <div style="border:inherit;margin:inherit;background-color:#e4e4b5;">
     2     <h3>Self---@Value<input class="btn btn-info" type="button" value="+1" @onclick="OnInput" /></h3>
     3     
     4     <h6>来自Family组件 @family?._familyValue</h6>
     5     <Son Value="@Value" OnValueChanged="OnValueChanged" />
     6 </div>
     7 @code {
     8     [Parameter]
     9     public int? Value { get; set; } = 0;
    10 
    11     public void OnInput()
    12     {
    13         Value++;
    14     }
    15 
    16     /// <summary>
    17     /// 获取上级Name为FamilyValue的Family组件
    18     /// </summary>
    19     [CascadingParameter(Name = "FamilyValue")]
    20     Family? family { get; set; }
    21 
    22     private void OnValueChanged(int? val)
    23     {
    24         Value = val;
    25     }
    26 }

    Parent.razor

     1 <div style="border:inherit;margin:inherit;background-color:#f6df6e;">
     2     <h3>Parent---@Value<input class="btn btn-info" type="button" value="+1" @onclick="OnInput" /></h3>
     3     
     4     <input type="text" name="name" @bind-value="_parentValue" />
     5     <CascadingValue Value="@_parentValue" Name="ParentValue">
     6         <Self Value="@Value" />
     7     </CascadingValue>
     8 </div>
     9 @code {
    10     [Parameter]
    11     public int? Value { get; set; } = 0;
    12 
    13     private string _parentValue = "ParentValue";
    14 
    15 
    16     public void OnInput()
    17     {
    18         Value++;
    19     }
    20 }

    Grand.razor

     1 <div style="border:inherit;margin:1.5rem 5rem 5rem 5rem;background-color:forestgreen;">
     2     <h3>Grand---@Value<input class="btn btn-info" type="button" value="点击+1,同时改变Family的值" @onclick="OnInput" /></h3>
     3     双向绑定:<input type="text" name="name" value="@Value" @onchange="ChangeParentValue" />
     4     <h6>@value</h6>
     5     <CascadingValue Value="this" Name="GrandValue">
     6         <Parent Value="@Value" />
     7     </CascadingValue>
     8 </div>
     9 @code {
    10     #region 双向绑定
    11     [Parameter]
    12     public int? Value { get; set; } = 0;
    13 
    14     /// <summary>
    15     /// 命名方法 绑定的参数名+Changed
    16     /// </summary>
    17     [Parameter]
    18     public EventCallback<int?> ValueChanged { get; set; }
    19 
    20     private async Task ChangeParentValue(ChangeEventArgs e)
    21     {
    22         if (e != null)
    23         {
    24             int.TryParse(e.Value!.ToString(), out var str);
    25             await ValueChanged.InvokeAsync(str);
    26         }
    27     }
    28     #endregion
    29 
    30     public async Task OnInput()
    31     {
    32         Value++;
    33         await ValueChanged.InvokeAsync(Value);
    34     }
    35 
    36     public string value { get; set; } = "Grand";
    37 
    38     public void SetValue(string value)
    39     {
    40         this.value = value;
    41     }
    42 
    43     public Action<string> Test => (value) => { this.value = value; StateHasChanged(); };
    44 
    45     public Action? State_HasChanged(Action Execute) => Execute + StateHasChanged;
    46 }

    Family.razor

     1 @page "/family"
     2     <Neighbor />
     3     <Divider />
     4     <div style="border:solid;background-color:lightsteelblue;">
     5         <h3>Family---@Value<input class="btn btn-info" type="button" value="+1" @onclick="OnInput" /></h3>
     6 
     7         <input type="text" name="name" @bind-value="_familyValue" />
     8         <CascadingValue Value="this" Name="FamilyValue">
     9             <Grand @bind-Value="@Value" />
    10         </CascadingValue>
    11 
    12     </div>
    13     @code {
    14         public int? Value { get; set; } = 0;
    15 
    16         public string _familyValue = "FamilyValue";
    17 
    18         public void OnInput()
    19         {
    20             Value++;
    21         }
    22 
    23     }


    Neighbor.razor

     1 @using BlazorApp.Shared.Services;
     2 <div style="border:solid;background-color:lightsteelblue;">
     3     <h3>Neighbor</h3>
     4     <h5>来至邻居家的: @Test</h5>
     5 </div>
     6 @code {
     7     public string? Test { get; set; }
     8 
     9 
    10     [Inject]
    11     public CommunicationToString? communicationToString { get; set; }
    12 
    13     protected override void OnInitialized()
    14     {
    15         base.OnInitialized();
    16         //注册服务
    17         communicationToString?.Register(Ceshi);
    18     }
    19 
    20 
    21     public Task Ceshi(string value)
    22     {
    23         Test = value;
    24         StateHasChanged();
    25         return Task.CompletedTask;
    26     }
    27 }
    CommunicationToString.cs
    1 namespace BlazorApp.Shared.Services
    2 {
    3     public class CommunicationToString : ServiceBase<string>
    4     {
    5 
    6     }
    7 }
     
    ServiceBase.cs
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Threading.Tasks;
     4 
     5 namespace BlazorApp.Shared.Services
     6 {
     7     public abstract class ServiceBase<TOption>
     8     {
     9         private Func<TOption, Task>? _Callback { get; set; }
    10 
    11         private IDictionary<string, Func<TOption, Task>>? _Callbacks { get; set; } = new Dictionary<string, Func<TOption, Task>>();
    12 
    13         /// <summary>
    14         /// 注册方法
    15         /// </summary>
    16         /// <param name="callback"></param>
    17         internal void Register(Func<TOption, Task> callback) => _Callback = callback;
    18 
    19         /// <summary>
    20         /// 回调方法
    21         /// </summary>
    22         /// <param name="option"></param>
    23         /// <returns></returns>
    24         public virtual void Callback(TOption option) => _Callback?.Invoke(option);
    25 
    26         /// <summary>
    27         /// 注册方法到集合
    28         /// </summary>
    29         /// <param name="key"></param>
    30         /// <param name="callback"></param>
    31         internal void Register(string key, Func<TOption, Task> callback) => _Callbacks?.Add(key, callback);
    32 
    33         /// <summary>
    34         /// 根据key值回调方法
    35         /// </summary>
    36         /// <param name="key"></param>
    37         /// <param name="option"></param>
    38         public virtual void Callback(string key, TOption option)
    39         {
    40             if (_Callbacks != null && _Callbacks.TryGetValue(key, out var callback))
    41             {
    42                 callback.Invoke(option);
    43             }
    44         }
    45     }
    46 }
  • 相关阅读:
    eclipse、idea安装lombok插件
    ContextLoaderListener加载过程
    web.xml 文件中一般包括 servlet, spring, filter, listenr的配置的加载顺序
    springboot
    root cause org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "XXX")
    Java MyBatis 插入数据库返回主键
    Mybatis异常There is no getter for property named 'XXX' in 'class com.xxx.xxx.UserAccountDTO
    web项目,ftl文件中的路径引入问题
    mybatis No enum const class org.apache.ibatis.type.JdbcType.Integer
    Restful、Jersey和JAX-RS
  • 原文地址:https://www.cnblogs.com/ysmc/p/16157803.html
Copyright © 2020-2023  润新知