如何获取IObservable的最后已知值?

时间:2016-07-06 16:01:18

标签: c# system.reactive rx.net

假设我正在使用Rx.Net构建图像编辑器。用户可以使用鼠标操作画布。应用的操作取决于当前选定的工具。例如,可能存在“绘图”工具和“擦除”工具。一次只能选择一个工具。

我有三个流;一个用于鼠标事件;一个用于通过单击鼠标发出的命令;和另一个工具选择:

IObservable<ITool> toolSelection;
IObservalbe<MouseState> mouse;
IObservable<ICommand> commands;

commands流取决于另外两个:当用户单击鼠标时发出命令,并且生成的命令取决于最后选择的工具。请注意,只有在用户单击鼠标时,才会在用户更改工具时发出 not 命令。

现在,我可以将最后选择的工具存储在如下变量中:

var selectedTool = defaultTool;
toolSelection.Subscribe(x => selectedTool = x);

我可以使用selectedTool构建commands流:

var commands = mouse.Select(x => selectedTool.CreateCommand(x));

但是,这似乎不是“反应性”的做事方式。我可以使用流组合实现相同的逻辑吗?

我查看了CombineLatest但是当用户切换工具时会导致产生不需要的事件。我只希望在用户点击时发出命令。

1 个答案:

答案 0 :(得分:4)

听起来你需要.Switch()

试试这段代码:

IObservable<ICommand> commands =
    toolSelection
        .Select(t => mouse.Select(m => t.CreateCommand(m)))
        .Switch();

在这种情况下,扩展方法.Switch()采用IObservable<IObservable<ICommand>>并通过获取外部observable生成的最新observable并将其生成IObservable<ICommand>并将其转换为// Add Menu Meta Boxes function add_menu_item_box() { add_meta_box( 'menu-name', __( 'Menus'), 'menu_meta_box_callback', 'menus', 'advanced', 'high'); } add_action( 'add_meta_boxes', 'add_menu_item_box' ); 处置以前的。

或者,用更多的英语术语来说,每当用户点击一个新工具时,你就可以在一个不错的查询中使用最新工具构建鼠标命令流。