【问题标题】:Event that passes a List<string> from child to parent将 List<string> 从子级传递给父级的事件
【发布时间】:2021-02-20 01:49:25
【问题描述】:

我正在尝试将List&lt;string&gt; 从孩子传递给父母。我在父组件中定义了一个Action&lt;List&lt;string&gt;&gt;,并将它作为参数传递给子组件。当子组件内发生事件时,预期结果是使用回调将更新的List&lt;string&gt; 发送给父组件。

我在&lt;TagComponent UpDateNewTags="UpdateTags"&gt;&lt;/TagComponent&gt; 的父组件中收到编译器错误Argument 2: cannot convert from 'method group' to 'EventCallback'。如果将 UpdateTags 更改为 UpdateTags() 我会得到一个不同的错误。我还尝试将UpdateTags 方法作为@(()=&gt;UpdateTags) 传递,但这也不起作用。现在,我可以开始将我想要传递给父级的信息放入会话本地存储中,并发出信号让父级从那里获取它,但这是承认失败。

如何使用事件回调按需将List&lt;string&gt; 从子级传递给父级?

    //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; }

【问题讨论】:

    标签: c# events blazor blazor-webassembly


    【解决方案1】:

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

    标签列表.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" }};
        }
    

    标签.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 对象都绑定到一个输入文本元素...当您更新给定的输入元素并跳出 Tab 时,将触发 OnTagChanged 事件处理程序,其中更新当前Tag 对象的 Title 字段以反映新的更改,然后使用参数 TagList 调用 TagListChanged EventCallback。发生这种情况时,Index页面中定义的TagList对象被更新,然后自动调用StateHasChanged方法重新渲染页面。

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

    【讨论】:

    【解决方案2】:

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

    @using Microsoft.AspNetCore.Components 
    

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

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

    EventCallBack Blazor Documentation

    要跨组件公开事件,请使用 EventCallback。父组件可以为子组件的 EventCallback 分配回调方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      相关资源
      最近更新 更多