在blazor中添加动态组件列表

时间:2018-05-11 19:57:58

标签: c# asp.net-core blazor

我刚开始看一下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但是对于列表我有下一个问题:

  • 我创建了一个<li>组件只是为了测试组件的功能,这里是组件视图
<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();

    };
}

当我加载第一个元素时正确加载: enter image description here

但是当我进入第二个时,所有这些都被替换为最后一个:

enter image description here

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

你太复杂了。您无需动态实例化组件以使此方案有效。

你可以做一个:

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

组件将为您实例化。

另请参阅here如何使参数适用于您的组件。

答案 1 :(得分:0)

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