简体   繁体   English

如何将这两个命令合而为一?

[英]How do I combine these two commands into one?

In the body of my class, I have this line of code: 在我的课程正文中,我有以下代码行:

private ReactiveCommand<object> _displayCommand = ReactiveCommand.Create();

In the class constructor, I set up a subscription: 在类构造函数中,我设置了一个预订:

_displayCommand.Subscribe(_ =>
{
    MessageBox.Show("Button clicked.");
});

Is it possible to write some sort of extension method to effectively combine these two commands into one, so with a single function call we can call both ReactiveCommand.Create(), and create a subscription using Reactive Extensions (RX)? 是否可以编写某种扩展方法来有效地将这两个命令组合为一个,因此通过一个函数调用,我们既可以调用ReactiveCommand.Create(),又可以使用响应式扩展(RX)创建预订?

This would group all logically related code together, and make the ViewModel much cleaner. 这会将所有与逻辑相关的代码组合在一起,并使ViewModel更加整洁。

Update 更新资料

This is what I have so far (thanks to @jt000): 这是我到目前为止(感谢@ jt000)的内容:

public static ReactiveCommand<object> CreateAndSubscribe(Func<object> fn)
{
    var displayCommand = ReactiveCommand.Create();
    displayCommand.Subscribe<object>(_ => fn.Invoke());
    return displayCommand;
}

private ReactiveCommand<object> _displayCommand = CreateAndSubscribe(() =>
{
    return MessageBox.Show("Hello");
});

public ReactiveCommand<object> DisplayCommand
{
    get { return _displayCommand; }
    protected set { _displayCommand = value; }
}

However, I need to occasionally insert the call .Buffer(TimeSpan.FromSeconds(1). between displayCommand and .Subscribe(fn) , and this function is not generic enough to do that. What I really need is some way of passing the entire subscription in to CreateAndSubscribe - perhaps some Func that takes an IObservable ? 但是,我有时需要在displayCommand.Subscribe(fn)之间插入调用.Buffer(TimeSpan.FromSeconds(1). .Subscribe(fn) ,并且此函数不够通用,我真正需要的是某种方式来传递整个订阅CreateAndSubscribe也许某些需要IObservable Func

This means I could use something like the following function call: 这意味着我可以使用以下函数调用:

private ReactiveCommand<object> _displayCommand = 
    CreateAndSubscribe(o => o.Subscribe(() =>
                              {
                                  return MessageBox.Show("Hello");
                              }));

and if I wanted to insert .Buffer(TimeSpan.FromSeconds(1)) : 并且如果我想插入.Buffer(TimeSpan.FromSeconds(1))

private ReactiveCommand<object> _displayCommand = 
    CreateAndSubscribe(o => o.Buffer(TimeSpan.FromSeconds(1)).Subscribe(() =>
                              {
                                  return MessageBox.Show("Hello");
                              }));

This API is actually intentionally missing, because there is no elegant way for Create to return both the ReactiveCommand and the IDisposable result from Create . 这个API是故意丢失,因为没有为没有优雅的方式Create返回两个 ReactiveCommand IDisposable从结果Create You could do something ugly with out parameters, but it'd end up being pretty cumbersome. 可以out参数的情况下做一些丑陋的事情,但最终会很麻烦。

While I definitely also sometimes miss a CreateWithAction or something like it, immediate Subscribe s are kind of defeating the composability aspect of RxUI; 尽管我有时肯定还会错过CreateWithAction或类似的东西,但是即时Subscribe却在击败RxUI的可组合性方面; this API makes it harder to put stuff together, not easier. 这个API使得将内容放在一起变得更加困难 ,而不是那么容易。

Would this work? 这行得通吗?

public static ReactiveCommand<object> CreateAndSubscribe(Func<object> fn) 
{
    var displayCommand = ReactiveCommand.Create();
    displayCommand.Subscribe(fn);
    return displayCommand;
}

Usage: 用法:

CreateAndSubscribe(_ => MessageBox.Show("hi"));

Yes, but there's not much point because instance members aren't in scope when defining a field. 是的,但是没有什么意义,因为在定义字段时实例成员不在范围内。 The handlers you pass to Subscribe can't reference any of the view model's fields or call any of its methods. 您传递给Subscribe的处理程序无法引用视图模型的任何字段或调用其任何方法。 You wouldn't be able to do much more than what you've shown in your example, such as call MessageBox.Show or something like that. 您将无法完成示例中显示的内容,例如调用MessageBox.Show或类似的东西。

Put something like this in a static class. 将这样的东西放在静态类中。

   public static void CreateAndSubscribe(this displayCommand)
    {
        displayCommand = ReactiveCommand.Create();
        displayCommand.Subscribe(_ =>
        {
            MessageBox.Show("Button clicked.");
        });
    }

Access it like any other extension method: 像其他任何扩展方法一样访问它:

_displayCommand.CreateAndSubscribe();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM