2014-01-25 74 views
3

我正在使用ReactiveUI框架來搜索世界各地的機場列表。ReactiveUI/Reactive Extensions:如何清除ObservableAsPropertyHelper

我已經設置了ObservableAsPropertyHelper,它是ViewModel中SearchTerm屬性中建議機場的輸出。以下是ObservableAsPropertyHelper的定義。在視圖中,我有一個綁定到這個屬性的列表框。我希望能夠明確清除列表框(因爲一旦用戶選擇了一個建議的項目,我想用選定的機場填充SearchTerm並清除建議的列表)。有沒有一種優雅的方式來實現這一點?

var searchTerms = this.ObservableForProperty(x => x.SearchTerms).Where(x => canSearch).Value().Throttle(TimeSpan.FromMilliseconds(500)); 
var searchResults = searchTerms.SelectMany(SearchAirports); 
var latestResults = searchTerms.CombineLatest(searchResults, (s, r) => r.SearchTerm != s ? null : r.AirportLiteWithWeights).Where(x => x != null); 
_airportLiteWithWeights = latestResults.ToProperty(this, x => x.AirportLiteWithWeights); 

回答

2

這是我會怎麼做 - 這是一個有點棘手,因爲事件的實際順序反饋到自身(即:選擇項目設置SearchTerms)

// The act of selecting an item is very ICommand'y, let's model it 
// as such. 
ReactiveCommand SuggestionItemSelected = new ReactiveCommand(); 

// Important to *not* signal a change here by touching the field 
// so that we avoid a circular event chain 
SuggestionItemSelected.Subscribe(x => _searchTerms = x); 

// NB: Always provide a scheduler to Throttle! 
var searchTerms = this.WhenAnyValue(x => x.SearchTerms) 
    .Where(x => canSearch) 
    .Throttle(TimeSpan.FromMilliseconds(500), RxApp.MainThreadScheduler); 

// Select + Switch will do what you were trying to do with CombineLatest 
var latestResults = searchTerms 
    .Select(SearchAirports); 
    .Switch() 

// The listbox is the combination of *Either* the latest results, or the 
// empty list if someone chooses an item 
var latestResultsOrCleared = Observable.Merge(
    latestResults, 
    SuggestionItemSelected.Select(_ => new List<Results>())); 

latestResultsOrCleared 
    .ToProperty(this, x => x.AirportLiteWithWeights, out _airportLiteWithWeights); 
+0

感謝保羅! 但_searchTerms = x不更新UI .... btw ..我今天學到了一些新東西。 Switch()方法確實適用於這種情況!謝謝! – icube

+0

謝謝保羅,我能夠使用這個解決方案。不過,我使用的是RxUI 7,我基本上使用了一個空命令來實現這一點。有沒有一個更優雅的解決方案,這個版本是沒​​有ReactiveCommand.Create();所以我使用 this.CancelCommand = ReactiveCommand.Create(()=> {}); – Saxar