首先发出Observable,使用第二个Observable作为条件

时间:2017-12-11 23:45:07

标签: c# xamarin xamarin.forms reactiveui

我有一个用于更新数据模型的ViewModel。当ViewModel属性更改时,我想更新数据模型上的相关属性并保存它。

但是,这意味着我必须要小心。例如,我不想在加载任何模型之前保存。所以我引入了IsLoaded属性。

加载数据的例程如下所示:

public ViewModel()
{
    IsLoaded = false;
}

private async Task Load()
{
    IsLoaded = false;

    var UnitAssesment = await Task.Run(() =>
    {
       return App.Repo.GetUnitAssessment( id );
    });

    Title = UnitAssessment.Title;
    Comment = UnitAssessment.Comment;

    IsLoaded = true;
}

最初设置ViewModel的属性,然后我设置了从ViewModel到数据模型的单向绑定:

this.WhenAnyValue( x => x.Comment )
  .Subscribe( x => {
    if ( !IsLoaded ) return;

    UnitAssessment.Comment = x.Item1;
    SaveUnit();
  });

这有效,但对于多个属性来说并不是很简洁。所以我开始尝试:

this.WhenAnyValue( x => x.Comment, x => x.IsLoaded )
  .Where( x => x.Item2 )
  .Subscribe(x => {
    UnitAssessment.Comment = x.Item1;
    SaveUnit();
  });

几乎同样的事情。问题是当IsLoaded设置为true时,Observable会触发。这导致数据模型使用相同的数据重新保存。

我想做的是这样的事情:

var isNotLoaded = this.WhenAnyValue( x => x.IsLoaded ).Where( x => !x );

this.WhenAnyValue( x => x.Comment )
  .ExceptWhen( isNotLoaded )
  .ToProperty(this, x => x.UnitAssessment.Comment );

PropertyChanged += ( sender, e ) => SaveUnit();

或监视2 Observables,但仅在第一个更改时触发。在Rx.NET中有这样的东西吗?有没有更好的方法来实现这一目标?

1 个答案:

答案 0 :(得分:2)

我相信你应该可以使用WithLatestFrom()功能。它的作用类似于CombineLatest(),但不是每当从任一源接收到新值时都会发出结果,它只会在从单个源接收到新值时发出结果。

例如:

// The observable that we want the latest value from
var isLoaded = this.WhenAnyValue(x => x.IsLoaded);

// Setup a new observable that watches for changes
this.WhenAnyValue(x => x.Comment)

    // Combine it with the most recent value from the above observable
    .WithLatestFrom(isLoaded, (comment, loaded) => new { comment, loaded })

    // Filter for when we're loaded
    .Where(x => x.loaded)

    // Side-effects
    .Select(x => x.comment)
    .Do(comment => {
      UnitAssessment.Comment = comment;
      SaveUnit();
    })

    // Make sure that everything happens
    .Subscribe();

我无法为特定的C#函数找到易于使用的API文档,但我能够找到源代码: