如何使用 Blazor 动态添加 DOM 元素?

问题描述 投票:0回答:1

我有一个类似聊天的 Blazor 应用程序,我需要不断向其中添加 DOM 元素:

<EditForm model="this" OnValidSubmit="@Query">
    <div id="qrContainer">
        <div>
            <input type="text" @ref="queryElement" @bind="query" />
        </div>
        <div>
            <div id="output" @bind="response"></div>
        </div>
    </div>
</EditForm>
@code {
    private String query { get; set; } = null;
    private String response { get; set; }
    private ElementReference queryElement;

    private async Task Query(){
        // ...
            var responseString = await responseService.getResponseAsync(query);
            // Need to add DOM element to "output" here.
        // ...
    }
}

据我了解,JSInterop 不是执行此操作的首选方法。那么,如何以“Blazor”方式添加新的 DOM 元素?

dom blazor
1个回答
0
投票

我认为你的思考方向是错误的。 您会发现需要将新的

responseString
添加到 DOM 中。 您实际需要做的是让组件[在本例中为页面]根据数据状态处理 DOM 更新。

这是一个基于您的代码片段的非常简单的示例。

记录、保存数据的单例服务以及通知注册处理程序发生更改的事件。

public record Comment(DateTime TimeStamp, string Value);

public class ChatRoom
{
    public event EventHandler? ItemsChanged;
    private readonly List<Comment> _items = new();

    public IEnumerable<Comment> Items => _items.OrderByDescending(item => item.TimeStamp);

    public void PostComment(string comment)
    {
        _items.Add(new(DateTime.Now, comment));
        this.ItemsChanged?.Invoke(null, EventArgs.Empty);
    }
}

还有聊天页面 [在本例中为

Home
]。

@page "/"
@inject ChatRoom ChatRoom
@implements IDisposable
<PageTitle>Home</PageTitle>

<h1>Chat world!</h1>
<textarea class="form-control" @bind=_currentComment @bind:event="oninput" />

<div class="text-end m-2">
    <button class="btn btn-primary btn-sm" disabled="@_noComment" @onclick="AddComment">Add Comment</button>
</div>

@foreach (var item in ChatRoom.Items)
{
    <div class="bg-light m-2 p-2 border border-1 rounded-3">@item.Value</div>
}

@code {
    private string? _currentComment;
    private bool _noComment => string.IsNullOrWhiteSpace(_currentComment);

    protected override void OnInitialized()
        => this.ChatRoom.ItemsChanged += this.OnItemsChanged;

    private void AddComment()
    {
        if (_currentComment is not null)
            ChatRoom.PostComment(_currentComment);

        _currentComment = null;
    }

    public void OnItemsChanged(object? sender, EventArgs e)
        => this.InvokeAsync(this.StateHasChanged);   

    public void Dispose()
        => this.ChatRoom.ItemsChanged -= this.OnItemsChanged;
}

两个浏览器窗口交互:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.