初始化中的Mvvmcross视图模型导航不起作用

时间:2018-11-09 08:46:36

标签: c# xamarin xamarin.ios xamarin.android mvvmcross

我有一个登录视图和登录后要显示的另一个视图。我将MvvmCross与本机Xamarin.Android和Xamarin.iOS一起使用。

因此,我有2个视图模型,LoginViewModel和MenuViewModel。我这样注册appstart:

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 :(得分:0)

代替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>();
    }
}