ReactiveUI 仅在用户输入更改时验证
ReactiveUI Validate only when user input changes
我是 ReactiveUI 的新手,所以我坚持这个问题,我的错误消息显示在页面开始,而不是在用户输入更改之后。
我想我对 ComplexRule 有疑问。
所以这是我在 ViewModel 中的代码:
public LoginViewModel(IScreen screen)
{
HostScreen = screen;
NameRule = this.ValidationRule(
viewModel => viewModel.UserName,
name => name.Length > 2,
"You must specify a valid name longer then 2 sybols.");
//checks with Regexp password
PasswordRule = this.ValidationRule(
viewModel => viewModel.Password,
password => PasswordValidator.Validate(password),
"You must specify a valid password longer then 8 sybols with at least 1 digit, upper
case, lower case and special characters.");
var nameAndPasswordRules = this
.WhenAnyValue(
x => x.UserName,
x => x.Password,
(name, password) => NameRule.IsValid && PasswordRule.IsValid);
ComplexRule = this.ValidationRule(
_ => nameAndPasswordRules,
(vm, state) => !state ? "Username and Password should be both valid!" : string.Empty);
var canNavigate = this.IsValid();
NavigateToMainPage = ReactiveCommand.CreateFromObservable(() =>
{
return HostScreen.Router.NavigateAndReset.Execute(new MyTabbedViewModel(HostScreen));
}, canNavigate);
}
这是我的观点:
public LoginView()
{
InitializeComponent();
this.WhenActivated(disposables =>
{
this.Bind(ViewModel, vm => vm.UserName, v => v.username.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, vm => vm.NameRule, v => v.usernameErrors.Text)
.DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Password, v => v.password.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, vm => vm.PasswordRule, v => v.passwordErrors.Text)
.DisposeWith(disposables);
this.BindCommand(ViewModel, x => x.NavigateToMainPage, x => x.loginButton)
.DisposeWith(disposables);
});
}
所以我试图在用户输入更改(密码/用户名)后实现验证并显示适当的消息。
我从文档中获取了这个示例。
我尝试了几种方法并完成了这个。
不确定这是否是最好的方法,但它有效(
想听听你的意见,如果你知道如何做得更好。
我将 null
值分配给属性
[Reactive]
public string UserName { get; set; } = null;
[Reactive]
public string Password { get; set; } = null;
所以我们假设 null - 意味着它从未被使用过。
并将此类验证放在 ValidationRule 上
var name = this
.WhenAnyValue(x => x.UserName)
.Select(x => x == null || x?.Length > 2);
var password = this
.WhenAnyValue(x => x.Password)
.Select(x => x == null || PasswordValidator.Validate(x));
var nameAndPasswordRules = this
.WhenAnyValue(
x => x.UserName,
x => x.Password)
.DefaultIfEmpty()
.DistinctUntilChanged()
.SkipWhile(item => !string.IsNullOrWhiteSpace(item.Item1) && !string.IsNullOrWhiteSpace(item.Item2))
.Select(prop1 =>
!string.IsNullOrEmpty(prop1.Item1)
&& this.NameRule.IsValid
&& !string.IsNullOrEmpty(prop1.Item2)
&& this.PasswordRule.IsValid);
NameRule = this.ValidationRule(
_ => name,
(vm, state) => !state ? "You must specify a valid name longer then 2 sybols." : string.Empty);
PasswordRule = this.ValidationRule(
_ => password,
(vm, state) => !state ? "You must specify a valid password longer then 8 sybols with at least 1 digit, upper case, lower case and special characters." : string.Empty);
ComplexRule = this.ValidationRule(
_ => nameAndPasswordRules,
(vm, state) => !state ? "Username and Password should be both valid!" : string.Empty);
如你所见,我会 x == null || ...
意味着绕过第一次尝试,因为用户没有编辑条目
我是 ReactiveUI 的新手,所以我坚持这个问题,我的错误消息显示在页面开始,而不是在用户输入更改之后。
我想我对 ComplexRule 有疑问。 所以这是我在 ViewModel 中的代码:
public LoginViewModel(IScreen screen)
{
HostScreen = screen;
NameRule = this.ValidationRule(
viewModel => viewModel.UserName,
name => name.Length > 2,
"You must specify a valid name longer then 2 sybols.");
//checks with Regexp password
PasswordRule = this.ValidationRule(
viewModel => viewModel.Password,
password => PasswordValidator.Validate(password),
"You must specify a valid password longer then 8 sybols with at least 1 digit, upper
case, lower case and special characters.");
var nameAndPasswordRules = this
.WhenAnyValue(
x => x.UserName,
x => x.Password,
(name, password) => NameRule.IsValid && PasswordRule.IsValid);
ComplexRule = this.ValidationRule(
_ => nameAndPasswordRules,
(vm, state) => !state ? "Username and Password should be both valid!" : string.Empty);
var canNavigate = this.IsValid();
NavigateToMainPage = ReactiveCommand.CreateFromObservable(() =>
{
return HostScreen.Router.NavigateAndReset.Execute(new MyTabbedViewModel(HostScreen));
}, canNavigate);
}
这是我的观点:
public LoginView()
{
InitializeComponent();
this.WhenActivated(disposables =>
{
this.Bind(ViewModel, vm => vm.UserName, v => v.username.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, vm => vm.NameRule, v => v.usernameErrors.Text)
.DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Password, v => v.password.Text)
.DisposeWith(disposables);
this.BindValidation(ViewModel, vm => vm.PasswordRule, v => v.passwordErrors.Text)
.DisposeWith(disposables);
this.BindCommand(ViewModel, x => x.NavigateToMainPage, x => x.loginButton)
.DisposeWith(disposables);
});
}
所以我试图在用户输入更改(密码/用户名)后实现验证并显示适当的消息。 我从文档中获取了这个示例。
我尝试了几种方法并完成了这个。 不确定这是否是最好的方法,但它有效( 想听听你的意见,如果你知道如何做得更好。
我将 null
值分配给属性
[Reactive]
public string UserName { get; set; } = null;
[Reactive]
public string Password { get; set; } = null;
所以我们假设 null - 意味着它从未被使用过。
并将此类验证放在 ValidationRule 上
var name = this
.WhenAnyValue(x => x.UserName)
.Select(x => x == null || x?.Length > 2);
var password = this
.WhenAnyValue(x => x.Password)
.Select(x => x == null || PasswordValidator.Validate(x));
var nameAndPasswordRules = this
.WhenAnyValue(
x => x.UserName,
x => x.Password)
.DefaultIfEmpty()
.DistinctUntilChanged()
.SkipWhile(item => !string.IsNullOrWhiteSpace(item.Item1) && !string.IsNullOrWhiteSpace(item.Item2))
.Select(prop1 =>
!string.IsNullOrEmpty(prop1.Item1)
&& this.NameRule.IsValid
&& !string.IsNullOrEmpty(prop1.Item2)
&& this.PasswordRule.IsValid);
NameRule = this.ValidationRule(
_ => name,
(vm, state) => !state ? "You must specify a valid name longer then 2 sybols." : string.Empty);
PasswordRule = this.ValidationRule(
_ => password,
(vm, state) => !state ? "You must specify a valid password longer then 8 sybols with at least 1 digit, upper case, lower case and special characters." : string.Empty);
ComplexRule = this.ValidationRule(
_ => nameAndPasswordRules,
(vm, state) => !state ? "Username and Password should be both valid!" : string.Empty);
如你所见,我会 x == null || ...
意味着绕过第一次尝试,因为用户没有编辑条目