Tenho um componente que abrirá uma caixa de diálogo perguntando se você tem certeza de que deseja descartar as alterações ao alternar para uma página diferente. Coloquei em cada página da seguinte forma:
<ConfirmNavigation HasUnsavedChanges="@HasUnsavedChanges" />
E este componente inclui:
[Parameter]
public bool HasUnsavedChanges { get; set; }
private async Task OnBeforeInternalNavigation(LocationChangingContext context)
{
if (!HasUnsavedChanges)
return;
Meu problema é que na página pai, manipulando o clique de envio, eu tenho:
HasUnsavedChanges = false;
await Task.Delay(1);
Navigation.NavigateTo(gotoUrl);
Isso não funciona. O método retorna depois dessas 2 linhas de código e ConfirmNavigation
ainda considera HasUnsavedChanges
true.
Existe uma maneira de fazer algo para que o valor alterado de HasUnsavedChanges
o torne ConfirmNavigation
? Minha melhor aposta é adicionar um método para ConfirmNavigation
que defina o valor? Não gosto disso porque está contornando o HasUnsavedChanges="@HasUnsavedChanges"
que viola como os componentes devem interagir.
Seu problema é este. Quando você define
no pai você está atribuindo
false
a uma variável global no pai.Esse valor só é aplicado à propriedade
HasUnsavedChanges
no filho quandoparameters.SetParameterProperties(this);
é chamadoSetParametersAsync
durante uma cascata de renderização acionada por um evento de renderização no pai.bool
é um tipo de valor.Você pode documentar a ordem de execução adicionando isto a
ConfirmNavigation
E log de console para
OnBeforeInternalNavigation
.A solução mais simples para sua lógica é passar um objeto mutável como parâmetro em vez de um bool.
Agora você está passando uma referência, então ambos os componentes estão olhando para a mesma coisa. Você quase certamente pode perder o
await Task.Delay(1);
Toda a operação de prevenção de navegação é um pouco complicada de codificar. O manipulador registrado em
RegisterLocationChangingHandler
é chamado do Navigation Manager. Você tem controle limitado sobre a ordem de execução do código.Adicionar o registro do console mostrará a ordem em que o código é executado.
Não sou fã de fazer arremessos a
await Task.Delay(1);
menos que seja absolutamente necessário. Não consigo pensar em uma maneira melhor e entendo exatamente o porquê.