Как получить последнее известное значение IObservable?
Предположим, я создаю графический редактор с использованием Rx.Net. Пользователь может манипулировать холстом с помощью мыши. Применяемые манипуляции зависят от выбранного в данный момент инструмента. Например, может быть инструмент "рисовать" и "стирать". Только один инструмент может быть выбран за один раз.
У меня есть три потока; один для событий мыши; один для команд, выдаваемых щелчком мыши; и еще один для выбора инструментов:
IObservable<ITool> toolSelection;
IObservalbe<MouseState> mouse;
IObservable<ICommand> commands;
commands
Поток зависит от двух других: команды выдаются, когда пользователь щелкает мышью, а сгенерированная команда зависит от последнего выбранного инструмента. Обратите внимание, что команда не должна вводиться, когда пользователь меняет инструмент, только когда он щелкает мышью.
Теперь я могу сохранить последний выбранный инструмент в переменной следующим образом:
var selectedTool = defaultTool;
toolSelection.Subscribe(x => selectedTool = x);
я могу использовать selectedTool
построить commands
поток:
var commands = mouse.Select(x => selectedTool.CreateCommand(x));
Тем не менее, это не похоже на "реактивный" способ ведения дел. Могу ли я достичь этой же логики с помощью потоковых композиций?
Я смотрел на CombineLatest
но это вызывает нежелательные события, которые генерируются, когда пользователь переключает инструмент. Я хочу, чтобы команды выполнялись только тогда, когда пользователь нажимает.
1 ответ
Похоже, вам нужно .Switch()
,
Попробуйте этот код:
IObservable<ICommand> commands =
toolSelection
.Select(t => mouse.Select(m => t.CreateCommand(m)))
.Switch();
Метод расширения .Switch()
принимает, в этом случае, IObservable<IObservable<ICommand>>
и превращает его в IObservable<ICommand>
беря самую последнюю наблюдаемую, произведенную внешней наблюдаемой и производя из нее только ценности, и избавляясь от предыдущих.
Или, если говорить более английским языком, всякий раз, когда пользователь нажимает на новый инструмент, вы получаете поток команд мыши, созданный с использованием только самого последнего инструмента в одном интересном запросе.