Я создал службу сообщений, которая позволяет мне отправлять сообщения из одного компонента, а подписавшиеся компоненты могут подписаться. к событиям.
В большинстве случаев единственное, что необходимо сделать, — это сообщить другому компоненту о необходимости повторного рендеринга после обновления.Мой текущий сценарий и проблемы заключаются в следующем:
- У меня есть главная страница, на которой размещено несколько компонентов.
- Одним из компонентов на этой странице является модальное диалоговое окно, которое позволяет пользователю обновлять некоторые данные (приключение).
- Когда модальное окно После завершения обновления он запускает событие, уведомляющее подписчиков о его запуске. Затем подписчики вызывают StateHasChanged для обновления пользовательского интерфейса своего компонента.
Я пробовал устанавливать различные значения для компонента, используя async вместо void, и все, что я могу придумать, приводит к бесполезному повторному рендерингу.
Служба сообщений:
public interface IMessageService
{
event Action OnMessage;
event Func OnMessageAsync;
void SendMessage(string message);
void ClearMessages();
}
public class MessageService : IMessageService
{
public event Action OnMessage;
public event Func OnMessageAsync;
public void SendMessage(string message)
{
OnMessage?.Invoke(message);
}
public void ClearMessages()
{
OnMessage?.Invoke(null);
}
}
Блок кода для модального диалога
@code {
[Parameter] public entities.Adventure Adventure { get; set; }
private bool isBusy = false;
private DateTime startDate;
private DateTime endDate;
private int numberOfDays;
protected override async Task OnInitializedAsync()
{
//capture the original start and end dates so we can deetected if they have been altered
startDate = Adventure.StartDate;
endDate = Adventure.EndDate;
numberOfDays = (endDate - startDate).Days;
}
private async Task OnSubmit()
{
try
{
isBusy = true;
bool isDateChange = false;
if (startDate != Adventure.StartDate || endDate != Adventure.EndDate)
{
if ((Adventure.EndDate - Adventure.StartDate).Days != numberOfDays)
{
await DialogService.Alert("Your trip does not contain the same number of days. You will loose some of your itinerary items (tasks, activities, etc). Please select a date range with the same number of days as your original adventure. You can remove days individually later if necessary.", "Oops", new AlertOptions() { OkButtonText = "Okay" });
isBusy = false;
return;
}
else
{
isDateChange = true;
}
}
var updatedAdventure = await AdventureClient.UpdateAdventureDetails(Adventure, isDateChange);
MessageService.SendMessage("AdventureUpdated");
DialogService.Close(updatedAdventure);
}
catch (Exception ex)
{
await DialogService.Alert($"Something went wrong while trying to save your adventure {ex.Message}", "Oops", new AlertOptions() { OkButtonText = "Close" });
}
finally
{
isBusy = false;
}
}
}
Блок кода хост-страницы, которую необходимо повторно отрисовать
@code {
[Parameter] public Guid Id { get; set; }
private entities.Adventure? adventure;
protected override async Task OnInitializedAsync()
{
MessageService.OnMessage += MessageHandler;
await GetAdventure();
}
async Task GetAdventure()
{
try
{
adventure = await AdventureClient.GetAdventure(Id);
}
catch (Exception ex)
{
await DialogService.Alert($"Something went wrong while trying to fetch your adventure {ex.Message}", "Oops", new AlertOptions() { OkButtonText = "Close" });
}
}
private void MessageHandler(string message)
{
if (message != null && message == "AdventureUpdated")
{
//BUG: this only gets called the first time the modal updates and does not get called on subsequent modal updates. The event fires every time
StateHasChanged();
}
}
public void Dispose()
{
MessageService.OnMessage -= MessageHandler;
}
}
Подробнее здесь: https://stackoverflow.com/questions/783 ... s-one-time
Мобильная версия