Mvvmcross View Модель навигации в Initialize не работает - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть вид для входа в систему и еще один вид для отображения после входа в систему. Я использую MvvmCross с родными Xamarin.Android и Xamarin.iOS.

Поэтому у меня есть 2 viewmodels, LoginViewModel и MenuViewModel. Я регистрирую приложение так:

RegisterAppStart<LoginViewModel>(); 

В LoginViewModel я проверяю, вошел ли пользователь уже в систему. Если он вошел в систему, я хочу перейти к MenuViewModel и перестать показывать LoginViewModel.

public override async Task Initialize()
{
    await base.Initialize();
    await AppConfig.Initialize();

    bool isLoggedIn = _authService.IsUserLoggedIn();
    if (isLoggedIn)
    {
        await _navigationService.Navigate<NavControllerViewModel>();
        await _navigationService.Close(this);
    }            
}

Приведенный выше код не работает, и LoginView отображается вместо MenuView. Однако работает то, что навигация происходит после того, как LoginView полностью загружен и пользователь взаимодействует с ним. Итак, у меня есть команда для входа в систему пользователя, LoginCommand, которая регистрирует пользователя, и если эта операция прошла успешно, я перехожу к MenuViewModel. Что-то вроде:

 private async Task Login()
 {
    if (!string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password))
    {
        if (Validations.IsValidEmail(Username))
        {
            OAuthResponse response = await UserController.Instance.Login(Username, Password);

            if (response.Error != null)
            {
                //Login NOk
                Mvx.IoCProvider.Resolve<IUserDialogs>().Alert(response.Error.Msg);
            }
            else
            {
                //Login OK
                ShowMenuScreenCommand.Execute(null);
            }
        }
        else
        {
            Mvx.IoCProvider.Resolve<IUserDialogs>().Alert("LoginView_Alert_InvalidEmail".Translate());
        }
    }
    else
    {
        Mvx.IoCProvider.Resolve<IUserDialogs>().Alert("LoginView_Alert_MissingRequiredFields".Translate());
    }
}

С ShowMenuScreenCommand, определенным так:

public IMvxAsyncCommand ShowMenuScreenCommand
{
    get
    {
        _navigateCommand = _navigateCommand ?? new MvxAsyncCommand(async () => await _navigationService.Navigate<NavControllerViewModel>());
        return _navigateCommand;
    }
}

Почему навигация в методе Initialize () не работает?

Может быть, метод Initialize () модели представления не подходит для такой навигации?

Я пытался поместить логику IsUserLogedIn в другие методы жизненного цикла представления, такие как ViewAppearing (), ViewAppeared () и т. Д., Но безуспешно.

Спасибо!

1 Ответ

0 голосов
/ 18 ноября 2018

вместо RegisterAppStart<LoginViewModel>();

Вы можете зарегистрировать свой собственный MvxAppStart и оттуда проверить, вошел ли пользователь в систему и перейти ли прямо к вашему NavControllerViewModel, в противном случае перейдите к LoginViewModel. Вы даже можете внедрить свой сервис аутентификации в конструкторе.

Создайте свой MvxAppStart

public class AppStart : MvxAppStart
{
    private readonly IMvxNavigationService _navigationService;
    private readonly IAuthenticationService _authService;

    public AppStart(
        IMvxApplication application,
        IMvxNavigationService navigationService,
        IAuthenticationService authService)
        : base(application, navigationService)
    {
        _navigationService = navigationService ?? throw new ArgumentNullException(nameof(navigationService));
        _authService = authService ?? throw new ArgumentNullException(nameof(authService));
    }

    protected override async Task NavigateToFirstViewModel(object hint = null)
    {
        var isUserLoggedIn = _authService.IsUserLoggedIn();

        if (isUserLoggedIn)
        {
            await _navigationService.Navigate<NavControllerViewModel>();
        }
        else
        {
            await _navigationService.Navigate<LoginViewModel>();
        }
    }
}

Зарегистрируйте свой MvxAppStart

public class App : MvxApplication
{
    public override void Initialize()
    {
        RegisterCustomAppStart<AppStart>();
    }
}
...