ReactiveUI/Reactive Extensions: как очистить ObservableAsPropertyHelper

Я использую фреймворк ReactiveUI для поиска списка аэропортов мира.

Я настроил ObservableAsPropertyHelper, который является выходом предлагаемых аэропортов из свойства SearchTerm в ViewModel. Ниже приведено определение 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);

person icube    schedule 25.01.2014    source источник


Ответы (1)


Вот как я бы это сделал - это немного сложно, потому что фактическая последовательность событий возвращается сама по себе (т.е. выбор элемента устанавливает 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);
person Ana Betts    schedule 26.01.2014
comment
спасибо пол! но _searchTerms = x не обновляет пользовательский интерфейс... кстати... сегодня я узнал кое-что новое. метод Switch() действительно подходит в этой ситуации! Спасибо! - person icube; 27.01.2014
comment
Спасибо, Пол, я смог использовать это решение. Однако я использую RxUI 7 и, по сути, использую пустую команду для реализации этого. Есть ли более элегантное решение для этой версии, если нет ReactiveCommand.Create(); поэтому я использую this.CancelCommand = ReactiveCommand.Create(() =› {}); - person Saxar; 02.03.2017