将 List<string> 从 child 传递到 parent 的事件

Event that passes a List<string> from child to parent

我正在尝试将 List<string> 从 child 传递到 parent。我在 parent 中定义了一个 Action<List<string>> 并将其作为参数传递给 child 组件。当 child 组件中发生事件时,预期结果是使用回调将更新后的 List<string> 发送到 parent。

我在 <TagComponent UpDateNewTags="UpdateTags"></TagComponent> 上的 parent 组件中遇到编译器错误 Argument 2: cannot convert from 'method group' to 'EventCallback'。如果将 UpdateTags 更改为 UpdateTags(),我会得到一个不同的错误。我还尝试将 UpdateTags 方法作为 @(()=>UpdateTags) 传递,但这也不起作用。现在,我可以将要传递给 parent 的信息放入会话本地存储中,并向 parent 发送信号让其从那里获取信息,但这是认输。

如何使用事件回调按需将 List<string> 从 child 传递到 parent?

    //Parent 
      <TagComponent  UpDateNewTags="UpdateTags"></TagComponent>

    // Parent function
    public void UpdateTags (List<string> tags)
      {
        if (cpdto.NewTagTitles == null)
          {
            cpdto.NewTagTitles = new List<string>();
          }

        cpdto.NewTagTitles = tags;
      }
    

    //child component.  
    [Parameter]
    public Action<List<string>> UpDateNewTags { get; set; }

确保您没有遗漏 using 指令。如果我没记错的话你需要:

@using Microsoft.AspNetCore.Components 

此外,不要使用 Action,而是使用 EventCallback:

[Parameter]
Public EventCallBack<List<string>> OnListUpdated {get; set;}

EventCallBack Blazor Documentation

To expose events across components, use an EventCallback. A parent component can assign a callback method to a child component's EventCallback.

下面的代码示例描述了如何创建一个包含 Tag 个对象列表的 TagList 对象,每个对象包含一个名为 Title 的字符串字段,如何绑定TagList 对象到子组件的 属性,如何在子组件中启用对 Tag 对象列表的编辑,以及如何将更改传播回父组件。

TagList.cs

public class TagList
    {
        public List<Tag> Tags { get; set; } = new List<Tag>() { new Tag { Title = "tag1" },
                                                            new Tag { Title = "tag2" },
                                                            new Tag { Title = "tag3" }};
    }

Tag.cs

public class Tag
{
   public string Title { get; set; }
} 

Index.razor

<Child @bind-TagList="@tagList.Tags"/>
<div>
    <p>List of tags</p>

   
    @foreach (var tag in tagList.Tags)
    {
        <p>@tag.Title</p>

    }

</div>

@code
    {

    private TagList tagList { get; set; } = new TagList();
}

Child.razor

<div>
    <p>List of tags to update</p>

    @foreach (var tag in TagList)
    {
        <p><input type="text" value="@tag.Title" @onchange="@((ChangeEventArgs args) => OnTagChanged(args, tag))"/></p> @*@onchange= "OnTagChanged"*@

     }

</div>

@code 
{
    [Parameter]
    public List<Tag> TagList { get; set; }

    [Parameter]
    public EventCallback<List<Tag>> TagListChanged { get; set; }

 private void OnTagChanged(ChangeEventArgs args, Tag tag)
    {
        tag.Title = args.Value.ToString();
        TagListChanged.InvokeAsync(TagList);
    }
}

请注意,每个 Tag 对象都绑定到一个输入文本元素...当您更新给定的输入元素并跳出时,会触发 OnTagChanged 事件处理程序,其中当前 [=15= 的 Title 字段] 对象被更新以反映新的变化,之后使用参数 TagList 调用 TagListChanged EventCallback。当发生这种情况时,Index页面中定义的TagList对象被更新,然后自动调用StateHasChanged方法重新渲染页面。

注意:Action委托不适合当前需求,因为Action是一个委托,封装了return无效的方法,但是你想要return一个字符串列表,所以你可以'使用它。如果有的话,Func 委托就是您所需要的。但是在 Blazor 中编写代码的正确方法是使用 EventCallback 'delegate',它实际上不是委托,而是一个为您生成正确委托的结构,并且还会自动调用 StateHasChanged 方法。