我试图绕过最近从6.5.2更新到7.0的reactiveUI,并且似乎包含了一些关于ReactiveCommand的重大变化。
以前用过的EG:
ViewModel中的:
public ReactiveCommand<Unit> DoLogin;
...
DoLogin = ReactiveCommand.CreateAsyncTask(
async x => {
IsBusy = true;
await Task.Delay(2500);
IsBusy = false;
return Unit.Default;
});
在视图中:
//bind the command
Observable.FromEventPattern(x => loginButton.Clicked += x, x => loginButton.Clicked -= x)
.Subscribe(args => ViewModel.DoLogin.Execute(null));
//do something after the dologin is complete
this.WhenAnyObservable(x => x.ViewModel.DoLogin)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe( x => {
DisplayAlert("login complete", "welcome", "OK");
}
);
但是现在在activui 7.0中,它是不同的,我不得不做一些改变,我无法让它正常工作:
ViewModel中的:
public ReactiveCommand<Unit, Unit> DoLogin;
...
DoLogin = ReactiveCommand.CreateFromTask(
async x => {
IsBusy = true;
await Task.Delay(2500);
IsBusy = false;
return Unit.Default;
});
在视图中:
//bind the command
Observable.FromEventPattern(x => loginButton.Clicked += x, x => loginButton.Clicked -= x)
.Subscribe(args => ViewModel.DoLogin.Execute());
//do something after the dologin is complete
this.WhenAnyObservable(x => x.ViewModel.DoLogin)
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe( x => {
DisplayAlert("login complete", "welcome", "OK");
}
);
命令代码仍然执行,但是WhenANyObservable订阅部分永远不会触发。它从不显示我的DisplayAlert。
我正在使用Xamarin Forms,如果这很重要,但即使在Windows Forms中我也会遇到相同的行为。
答案 0 :(得分:6)
问题是现在Execute()
是一个冷可观察对象,所以不是调用
ViewModel.DoLogin.Execute()
你必须致电
ViewModel.DoLogin.Execute().Subscribe()
您可以在release docs中详细了解ReactiveCommand
中的更改(ctrl + F&#34; ReactiveCommand更好&#34;)
顺便说一下 - 你可以通过在视图中使用绑定代替Observable.FromEventPattern
来简化生活。这在docs about ReactiveCommand中有所描述。这样你就可以避免在另一个Subscribe
调用中进行Subscribe
调用,这是一种代码味道。代码应该类似于:
this.BindCommand(
this.ViewModel,
vm => vm.DoLogin,
v => v.loginButton);
另一个旁注 - ReactiveCommand
将IsExecuting
公开为可观察的属性,因此您可能不需要单独的标记IsBusy
,