如何使用 Blazor 从动态文本框中检索数据

How to retrive data from dynamic text box using Blazor

MyCustomControl.razor

<input type="text" id="@id" />
@code {
     [Parameter]
    public string id { get; set; }
}

Test.Razor

@page "/test"

<button @onclick="@addCompoment">add text box</button>
<div class="simple-list-list">
    @if (componentListTest == null)
    {
        <p>You have no items in your list</p>
    }
    else
    {
        <ul>
            @foreach (var item in componentListTest)
            {
                @item<br/>
            }
        </ul>
    }
</div>

@functions {

    private List<RenderFragment> componentListTest { get; set; }
    private int currentCount { get; set; }
    private string TxtExample { get; set; }
    protected  void OnInit()
    {
        currentCount = 0;
        componentListTest = new List<RenderFragment>();
    }


    protected void addCompoment()
    {
        if(componentListTest==null)
        {
        componentListTest = new List<RenderFragment>();
        }
        componentListTest.Add(CreateDynamicComponent(currentCount));
        currentCount++;
    }


    RenderFragment CreateDynamicComponent(int counter) => builder =>
    {

        try
        {
            var seq = 0;
            builder.OpenComponent(seq, typeof(MyCustomControl));
            builder.AddAttribute(++seq, "id", "listed-" + counter);
            builder.CloseComponent();
        }
        catch (Exception ex)
        {

            throw;
        }


    };
}

动态添加文本框后,如何从文本框中检索所有输入数据(点击提交按钮后。) 如何与动态组件交互并获取值。 MyCustomControl 是组件,附加在 Test Razor Page 中。 为这些组件创建一个属性,如绑定值,以获取用户给出的输入字段数据

这类问题有多种解决方案,具体取决于您应用的总体设计、约束等。下面的解决方法很简单。一般来说,就是将添加的文本框的值传给父组件保存在列表对象中。父组件有一个按钮,单击时会显示文本列表。

下面是子组件的定义:

MyCustomControl.razor

    <input type="text" @bind="@Value" id="@ID" />

    @code {
        private string _value;

        public string Value
        {
            get { return _value; }

            set
            {
                if (_value != value)
                {
                    _value = value;
                    if (SetValue.HasDelegate)
                    {
                        SetValue.InvokeAsync(value);
                    }
                 }
             }
         }

        [Parameter]
        public string ID { get; set; }
        [Parameter]
        public EventCallback<string> SetValue { get; set; }
    } 

在父组件中的用法

    <button @onclick="@addCompoment">add text box</button>

    <div class="simple-list-list">
        @if (componentListTest == null)
        {
            <p>You have no items in your list</p>
        }
        else
        {
            <ul>
                @foreach (var item in componentListTest)
                {
                    @item
                    <br />
                }
            </ul>
        }
    </div>

    <p><button @onclick="@ShowValues">Show values</button></p>

    @if (Display)
    {
        <ul>
            @foreach (var value in values)
            {
                <li>@value</li>

            }
        </ul>
    }

    @code {

        public void SetValue(string value)
        {
           values.Add(value);
        }

    private List<RenderFragment> componentListTest { get; set; }
    private List<string> values = new List<string>();
    private int currentCount { get; set; }

    protected override void OnInitialized()
    {
        currentCount = 0;
        componentListTest = new List<RenderFragment>();
    }

    private bool Display;

    private void ShowValues()
    {
        if (values.Any())
        {
            Display = true;
        }
    }
    protected void addCompoment()
    {
        if (componentListTest == null)
        {
            componentListTest = new List<RenderFragment>();
        }
        componentListTest.Add(CreateDynamicComponent(currentCount));
        currentCount++;
    }


    RenderFragment CreateDynamicComponent(int counter) => builder =>
    {
        try
        {

           builder.OpenComponent(0, typeof(MyCustomControl));
            builder.AddAttribute(1, "id", "listed-" + counter);
            builder.AddAttribute(2, "SetValue", Microsoft.AspNetCore.Components.CompilerServices.RuntimeHelpers.TypeCheck<Microsoft.AspNetCore.Components.EventCallback<System.String>>(Microsoft.AspNetCore.Components.EventCallback.Factory.Create<System.String>(this, this.SetValue )));
            builder.CloseComponent();
            }
            catch (Exception ex)
            {
                throw;
            }
        };
    }

注:

  1. 请注意我添加到 CreateDynamicComponent 的构建器中的 SetValue 属性。这为 EventCallback<string> 类型的 MyCustomControl 提供了一个组件参数,它被分配给 SetValue 参数 属性:
    [Parameter]
    public EventCallback<string> SetValue { get; set; } 

并用于(触发父组件中也叫SetValue的方法,名字可以改)将子组件的变化值传递给父组件。

  1. 使用代码代替函数。

  2. 请注意,我对您的代码进行了一些修改:OnInitialized 而不是 OnInit(已过时),序列号不应按照您的方式创建。参考this article written by Steve Sanderson ...

希望这对您有所帮助...