#blazor #blazor-client-side #blazor-webassembly
#blazor #blazor-на стороне клиента #blazor-веб-сборка
Вопрос:
Я довольно новичок в Blazor, поэтому эта проблема может быть скорее логической, чем реальной проблемой кодирования. По сути, мой родительский компонент отображает список на основе списка дочернего компонента. Проблема в том, что список не обновляется.
Для простоты я создал небольшую демонстрацию проблемы. Вот мой основной компонент:
@page "/"
<Counter @ref="MyCounter" />
<ul>
@if (MyCounter?.TheList != null)
{
@foreach (string s in MyCounter.TheList)
{
<li>@s</li>
}
}
</ul>
@code {
Counter MyCounter;
}
Вот мой компонент-счетчик:
<div>
<button @onclick="AddToList">Add to list</button>
</div>
@code {
public List<string> TheList {get;set;} = new List<string>();
private Random Rnd = new Random();
private void AddToList()
{
int length = 5;
var str_build = new System.Text.StringBuilder();
char letter;
for (int i = 0; i < length; i )
{
double flt = Rnd.NextDouble();
int shift = Convert.ToInt32(Math.Floor(25 * flt));
letter = Convert.ToChar(shift 65);
str_build.Append(letter);
}
TheList.Add(str_build.ToString());
Console.WriteLine($"Added to the list: {str_build.ToString()}");
Console.WriteLine($"The list now has {TheList.Count} items");
}
}
Поведение, которое я ожидаю увидеть, заключается в том, что каждый раз, когда я нажимаю кнопку, я должен видеть, как в <ul>
теге появляется новая добавленная строка. Однако на самом деле происходит то, что ничего не отображается. В журнале консоли отображается новая строка плюс количество элементов в списке, и это все точно. Blazor просто не выполняет повторный рендеринг, вероятно, потому, что я должен каким-то образом уведомить его, что ему необходимо выполнить повторный рендеринг. Как я могу заставить мое ожидаемое поведение работать?
Я здесь создал версию проблемы.
Ответ №1:
Я вижу, вы сохраняете список элементов в дочернем компоненте. В подобном случае вы должны указать родительскому компоненту выполнить повторный запуск самостоятельно, потому что у меня есть новые данные для отображения. Вы можете сделать это, добавив обратный вызов события к дочернему компоненту и подключившись к событию в родительском, где вы вызываете StateHasChanged()
метод. Код см. в модифицированном fiddler
Другим вариантом может быть перемещение списка в родительский компонент и передача списка в качестве параметра дочернему компоненту. В этом случае вам не понадобилось бы событие.
Комментарии:
1. Я последовал вашему совету и выбрал второй подход. Он по-прежнему не работает. Я сделал список параметром в дочернем компоненте. Вот пример: blazorfiddle.com/s/brcf1nvi
2. Приношу свои извинения за частично правильный ответ выше. Когда я думаю о компоненте, я хочу спроектировать его в стиле master details. Мастер хранит данные, а дочерние элементы «запускают» события. Точно так же, как компоненты в Winforms. Я изменил пример и прошу прощения за путаницу. Кстати, эта форма дизайна компонента больше похожа на примеры в официальных документах. blazorfiddle.com/s/z8om40ux
Ответ №2:
@icemanind, я взглянул наhttps://blazorfiddle.com/s/brcf1nvi. Вы можете заставить это работать, настроив двустороннюю привязку.
Ключевыми изменениями являются:
- изменение в родительском индексе.razor
<Counter @ref="MyCounter" @bind-TheList="TheList" />
- добавить в дочерний счетчик.razor
public EventCallback<List<string>> TheListChanged {get;set;}
Пожалуйста, взгляните на https://blazorfiddle.com/s/l5ucab8d.