2017-12-11 11 views
0

데이터 모델을 업데이트하는 데 사용되는 ViewModel이 있습니다. ViewModel 속성이 변경되면 데이터 모델의 관련 속성을 업데이트하여 저장하려고합니다.처음보기 Observable, second use 조건부로 Observable을 사용합니다.

그러나 지금은 조심해야합니다. 예를 들어 어느 모델이로드되기 전에 저장하지 않으려합니다. 그래서 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; 
} 

이 뷰 모델의 속성을 설정합니다 : 데이터를로드

루틴은 다음과 같이 보입니다

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에서 이와 같은 것이 있습니까? 이것을 달성하기위한 더 좋은 방법이 있습니까?

답변

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 문서를 찾을 수 없습니다, 그러나 나는 소스 찾을 수 있었다 :

+0

NuGet 패키지 (https://www.nuget.org/)를 설치하려고 시도했습니다. 패키지/System.Reactive.Linq /). 그러나 라이브러리는 내 PCL/Xamarin Forms 라이브러리에 설치되지 않습니다. 수치스러운 점은 – Mitkins

+0

ReactiveUI 7.4 이하 버전을 사용하고있는 경우 [Rx-Linq] (https://www.nuget.org/packages/rx-linq/2.2.5)를 설치해야합니다. 올바른 ReactiveUI 버전을 PCL에 설치하면 자동으로 – Qonstrukt