bugfix> xamarin > 投稿

Xamarin iOSでReactive UIの実験を開始しましたが、ルーティングの処理方法に混乱しています。

次のような典型的な「LoginViewModel」を見てみましょう。

public class LoginViewModel : ReactiveObject
{
    private readonly ReactiveCommand loginCommand;
    public ReactiveCommand LoginCommand => this.loginCommand;
    string username;
    public string Username
    {
        get { return username; }
        set { this.RaiseAndSetIfChanged(ref username, value); }
    }
    string password;
    public string Password
    {
        get { return password; }
        set { this.RaiseAndSetIfChanged(ref password, value); }
    }
    public LoginViewModel()
    {
        var canLogin = this.WhenAnyValue(
            x => x.Username,
            x => x.Password,
            (u, p) => !string.IsNullOrEmpty(u) && !string.IsNullOrEmpty(p)
        );
        this.loginCommand = ReactiveCommand.CreateFromTask(async () =>
        {
            //Simulate login
            await Task.Delay(2000);
            return true;
        }, canLogin);
    }
}

そして、ViewDidLoad(コントローラー):

this.WhenActivated(d =>
{
    this.Bind(this.ViewModel, x => x.Username, x => x.Username.Text).DisposeWith(d);
    this.Bind(this.ViewModel, x => x.Password, x => x.Password.Text).DisposeWith(d);
    this.BindCommand(this.ViewModel, x => x.LoginCommand, x => x.LoginButton).DisposeWith(d);
});

これにより、これらのUITextFieldsとログインボタンの有効状態+ OnTouchUpInsideの値が効果的にバインドされます。

さて、deドキュメンテーション vm-routingについて次を見つけることができます。Android、iOS Native:動作させるのは非常に難しい

ここで私のオプションは何でしょうか?

DidLogInプロパティ(bool)を公開し、その上で(ビュー内で)リッスンします:

this.WhenAnyValue(x => x.ViewModel.DidLogIn)
    .ObserveOn(RxApp.MainThreadScheduler)
    .Subscribe(() => {
        //Routing logic here
    });

ビュールーティングを処理する他の方法がありますか(vmルーティングではありません)、これに関する情報はほとんど見つかりません

回答 1 件
  • Xamarin FormsでのReactiveUIのルーティングは非常に簡単です。XamarinAndroid/iOSの歴史は異なりますが、ReactiveUIの相互作用を試すことができます。例:

    public class LoginViewModel : ReactiveObject
    {
        private readonly Interaction<Unit, Unit> _navigate;
        public Interaction<Unit, Unit> Navigate => Navigate;
        public ReactiveCommand<Unit,bool> LoginCommand { get; set; }
    
        public LoginViewModel()
        {
            var canLogin = this.WhenAnyValue(
            x => x.Username,
            x => x.Password,
            (u, p) => !string.IsNullOrEmpty(u) && !string.IsNullOrEmpty(p));
            _navigate = new Interaction<Unit, Unit>();
            LoginCommand = ReactiveCommand.CreateFromTask<Unit, bool>(async _ =>
            {
                /*Logic here*/
                return true;
            }, canLogin);
           LoginCommand.Subscribe(async result => 
            {
                if (result)//this logic gets executed on your view by registering a handler :D
                    await await _navigate.Handle(Unit.Default) ;
                else
                    {}
            });
        }
    }
    
    

    あなたの意見では

    this.WhenActivated(disposables =>
    {
       //bindings...
       //Register a handler:
       ViewModel.Navigate.RegisterHandler(async interaction =>
       {
           await NavigationLogic();
           interaction.SetOutput(Unit.Default);
       }).DisposeWith(disposables);
    });
    
    

    この例は完全ではありませんが、それを行う1つの方法です。

    これがお役に立てば幸いです。インタラクションの詳細については、https://reactiveui.net/docs/handbook/interactions/をご覧ください。

    Xamarin Android + ReactiveUIにも例があります:https://github.com/bl8/ReactivePhoneword

    よろしく

あなたの答え