ReactiveUI 7.0,ReactiveCommand,Subscribe永远不会触发?

时间:2016-11-24 03:22:43

标签: xamarin.forms system.reactive reactiveui

我试图绕过最近从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中我也会遇到相同的行为。

1 个答案:

答案 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);

另一个旁注 - ReactiveCommandIsExecuting公开为可观察的属性,因此您可能不需要单独的标记IsBusy