【问题标题】:add list of dynamic components in blazor在 blazor 中添加动态组件列表
【发布时间】:2018-10-22 06:56:34
【问题描述】:

我刚刚开始查看 blazor (v0.3) 并进行了一些测试,我想使用 blazor 添加一个列表

首先我创建了一个List<string> 来测试同一页面中的一个简单列表

<ul>
    @foreach (var item in listItems)
    {
        <li>@item</li>
    }
</ul>


@functions {

    private List<string> listItems = new List<string>();
    private string newItem;

    private void AddItem()
    {
        if (string.IsNullOrEmpty(newItem))
            return;

        listItems.Add(newItem);
        newItem = "";
    }

}

这很好,当我添加它时将每个元素添加到列表中。但是后来,我尝试添加组件,添加单个组件很容易,基于这个问题here 但对于一个列表,我遇到了下一个问题:

  • 我创建了一个&lt;li&gt; 组件只是为了测试组件的功能,这里是组件视图
<li id="@ID">
    @Text
</li>   




@functions {
  [Parameter]
  string Text { get; set; } 
  [Parameter]
  string ID { get; set; }
}
  • 然后在父视图中
<input type="text" bind="TxtExample" name="inpAdd"/>
  <button onclick="@addCompoment">add comp1</button>
<div class="simple-list-list">
    @if (!componentListTest.Any())
    {
        <p>You have no items in your list</p>
    }
    else
    {
        <ul>
            @foreach (var item in componentListTest)
            {
                @item
            }
        </ul>
    }
</div>

@functions {

    private List<RenderFragment> componentListTest { get; set; }
    private int currentCount {get; set;}
    private string TxtExample { get; set; }

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


    protected void addCompoment()
    {

        componentListTest.Add(CreateDynamicComponent(currentCount));
        currentCount++;
    }


    RenderFragment CreateDynamicComponent(int counter) => builder =>
    {
        var seq = 0;
        builder.OpenComponent(seq, typeof(listExample));
        builder.AddAttribute(++seq, "Text", "text --  "+TxtExample);
        builder.AddAttribute(++seq, "id","listed-"+counter);

        builder.CloseComponent();

    };
}

当我加载第一个元素时正确加载:

但是当我进入第二个时,它们都被替换为最后一个:

知道发生了什么吗?

【问题讨论】:

  • 我建议使用最新版本,目前是 0.3。
  • yup 是 0.3 而不是 0.2

标签: c# asp.net-core blazor


【解决方案1】:

你把它弄得太复杂了。您无需动态实例化组件即可使此方案正常工作。

你可以做一个:

<ul>
    @foreach (var item in listItems)
    {
        <myComponent bind-myVar="@item"></myComponent>
    }
</ul>

组件将为您实例化。

另请参阅here 如何使参数在您的组件上起作用。

【讨论】:

  • mi 问题不在列表中,问题是动态加载组件。我会看看链接顺便说一句
  • 我的观点是,在 99% 的情况下,您不需要以编程方式实例化。
  • 哈哈我一直在寻找答案,但完全忘记了这是您添加动态内容的意思。谢谢你提醒我。我想我们中的一些人需要一段时间才能摆脱向 DOM 添加内容的旧思维方式
  • 这对于他的用例来说可能是一个不错的选择,因为列表中的所有对象都是相同的类型。如果您的列表由多态对象组成,这不是一个好的选择。假设他有一个水果类型的集合。该列表可以包含香蕉、苹果和橙子,它们是水果类型的后代。假设它们将以不同的方式呈现。使用参数只会失去封装和关注点分离的所有好处,因为封闭组件需要知道如何渲染每个水果。此外,添加另一种类型也需要更改封闭组件。
【解决方案2】:

这是因为TxtExample 对组件来说是全局的。当 Blazor 检测到潜在的 UI 更改时,它会重新计算整个组件并使用任何差异更新 DOM。因此,当您更改文本框时,TxtExample 会更新,然后 Razor 会重新计算,为所有行插入 TxtExample 的新值。

【讨论】:

  • 我知道你的意思,但在第一个例子中 List&lt;string&gt; @newItem 对组件来说也是全局的。但是当我添加一个项目时,所有旧项目都会保留这些值。有什么想法吗?
  • 我有点困惑CreateDynamicComponent lambda 是如何工作的,比如builder 来自哪里,或者listExample 是什么,但我猜RenderFragment每次都重新计算,而 newItem 不是因为它是一个值类型。尝试创建一个字符串列表,表示 TxtExample 的所有条目,以便它可以循环遍历并为每个条目显示一个条目。
猜你喜欢
  • 2021-07-04
  • 1970-01-01
  • 1970-01-01
  • 2018-05-13
  • 1970-01-01
  • 1970-01-01
  • 2020-04-05
  • 2022-09-28
  • 2021-11-23
相关资源
最近更新 更多