Родительский компонент не обновляется в Blazor Webassembly

#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.