【发布时间】:2018-11-09 08:46:36
【问题描述】:
我有一个登录视图和另一个登录后显示的视图。我将 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() 等,但没有成功。
谢谢!
【问题讨论】:
-
这也是一个愚蠢的导航位置。初始化并不能保证视图已经出现。因此,您可能正试图在另一个导航请求的中间进行导航。
ViewAppeared会是一个更好的地方来做这件事。但是,这意味着将显示当前的 ViewModel。在导航到 ViewModel 之前,您应该先进行检查,然后再进行IsLoggedIn检查。 -
@jotade 我不这么认为。我不想更改开始视图模型。我想从 Initialize 方法导航到另一个视图控制器。正如所指出的,这不是一个好的做法,所以我在我的应用中更改了导航的概念。
-
感谢@Cheesebaron 提供您的信息。这很有帮助。
标签: c# xamarin xamarin.ios xamarin.android mvvmcross