2017-08-18 1 views
4

RamUIをXamarin.Formsに使用すると、自動的に1回だけ実行される(最初のページが表示されている)ときに、そのユーザーが後でその実行をリクエストできるようにするコマンドをどのように作成しますか?イベント)?Xamarin.FormsでReactiveUIを使用してコマンドを1回だけ実行するには?

私はFromEventPatternを使用してAppearingイベントにコマンドをフックしましたが、ページに戻ったときに再び実行され、望ましくない動作です。

これは私のシナリオです:ユーザーがそれを含むページを開くと、自動的に読み込まれるリストが必要です。ユーザーは要素を選択し、その詳細を別のページ(NavigationPageを使用)で表示できますが、ユーザーがリストページに戻ると、それは発生しないはずです。ユーザーは、新しいデータをボタンで要求したり、リフレッシュすることができます。

ありがとうございます。

+3

あなたは 'FromEventPattern(... Appearing ...)を試しましたか?Take(1)'? – Dorus

+0

また、ボタンのクリックを聞くようにするには、その観測可能物と 'Merge'するだけです。 – Dorus

+0

はい@Dorus、それは動作しませんでした。しかしそれは良いアイデアでした。 – fferegrino

答えて

1

このシナリオはどのように処理したのですか。これに類似した動作が必要になります。この動作は、特定の既知の値が設定されている場合にのみコマンドを呼び出します。あなたのコンストラクタの最後で

// Only invoke the command when the property matches a known value that can't happen through normal execution 
this.WhenAnyValue(vm => vm.SomeProperty) 
       .Where(sp => sp == null) 
       .Throttle(TimeSpan.FromSeconds(.25), TaskPoolScheduler.Default) 
       .Do(_ => Debug.WriteLine($"Refresh the List")) 
       .InvokeCommand(GetList) 
       .DisposeWith(SubscriptionDisposables); 

は、設定SomePropertyはこの場合、既知の値

this.SomeProperty = null; // or some value that makes sense 

に一致するように、あなたはOnAppearingで手動でコマンドを起動する必要はありません - それが起こるとき、あなたのViewModel最初に構築され、ViewModelが廃棄されて再作成されるまで、再度実行されません。 それは私にはちょっとハック感があるようです。だから、より賢い、より多くの熟練したRxUIのウィザードがチャイムすることを望んでいますが、それは仕事を完了させます。あなたが代わりにOnAppearingコールを残すことを希望する場合

、あなたはまた、潜在的にあなたのReactiveCommandのcanExecuteプロパティを設定し、(両方のコマンドは、そうでない場合と同じ挙動するにもかかわらず)お使いのPullToRefreshアクションのために完全に異なるReactiveCommandを使用してこれを扱うことができます。このシナリオでは、最初にリストが移入された後にcanExecuteを常にfalseにしたいので、ユーザーがページに戻っても初期集計がトリガーされません。

var isInitialized = this.WhenAnyValue(vm => vm.IsInit).Select(_ => _ == false).DistinctUntilChanged(); 

InitList = ReactiveCommand.CreateFromTask(_ => 
{ 
    // get list 
}, isInitialized); 

RefreshList = ReactiveCommand.CreateFromTask(_ => 
{ 
    // essentially the same as InitList, but with different/no canExecute parameters 
}); 

InitList.ObserveOn(RxApp.MainThreadScheduler).Subscribe(result => 
{ 
    this.IsInit = false 
}).DisposeWith(SubscriptionDisposables); 

ここでの欠点は明らかに、である、あなたは、いくつかのロジックがドーロスヒントを使用して

+0

ありがとう、@ジョー、あなたのソリューションも動作し、私はViewModelからタスクを達成するために使用することができます。 – fferegrino

+0

@fferegrino - Dorus氏が提案したFromEventPatternソリューションも回答として提供していますか?それは他の人にとっては有用かもしれません。私は自分自身が好奇心です – Joe

2

を重複している:あなたのページのconsturctorであなただけの最初の1 Take、その後、イベントから観察可能なを作成する必要があります。

Observable.FromEventPattern(ev => Appearing += ev, ev => Appearing -= ev) 
      .Select(e => Unit.Default) 
      .Take(1) 
      .InvokeCommand(ViewModel.InitialCollectionLoad); 
0

多分私は誤解しているかもしれませんが、私はこれを頻繁に行うので、私はそうは思わないです。

私は、VM作成をコマンドの最初の実行のトリガとして使用します。次に、同じコマンドをXFのプル・ツー・リフレッシュ機能に関連付けます。

だから私のVMは、次のようになります。

public class MyVM 
{ 
    public MYVM() 
    { 
     this.refreshCommand = ...; 

     this 
      .refreshCommand 
      .Execute() 
      .Subscribe() 
       _ => {}, 
       _ => {}); 
    } 

    public ReactiveCommand<...> RefreshCommand => this.refreshCommand; 
} 

コマンドは、すぐにVMを作成するように実行されるので、データをできるだけ早く取得されるこの方法です。しかし、VMが再作成されたり、ユーザーがプル・トゥ・リフレッシュしない限り、再度実行されません。

関連する問題