【问题标题】:ReactiveCommand stopped working in ReactiveUI 6ReactiveCommand 在 ReactiveUI 6 中停止工作
【发布时间】:2017-03-01 03:45:59
【问题描述】:

我正在尝试使用 Progressive .NET 2014 的 James Nugent 实验室并将其转换为 ReactiveUI 6。目前我遇到了 CreateAsyncTask,它似乎永远不会运行任务代码。

VM 代码是这样的:

private IObservable<string> PretendToCallTheServer()
{
    return Observable.Return("Hello World")
        .Delay(TimeSpan.FromMilliseconds(2000), RxApp.TaskpoolScheduler);
} 

public PersonViewModel()
{
    _fullName = this.WhenAnyValue(vm => vm.FirstName, vm => vm.LastName, (f, l) => string.Format("{0} {1}", f, l))
                    .ToProperty(this, vm => vm.FullName);

    var firstAndLastFilled = this.WhenAnyValue(vm => vm.FirstName, vm => vm.LastName,
        (f, l) => !string.IsNullOrWhiteSpace(f) && !string.IsNullOrWhiteSpace(l));

    ChangeName = ReactiveCommand.CreateAsyncTask(firstAndLastFilled, async x => await PretendToCallTheServer());
    ChangeName.Subscribe(x => ServerResult = x);
}

private string _serverResult;
public string ServerResult
{
    get { return _serverResult; }
    set { this.RaiseAndSetIfChanged(ref _serverResult, value); }
}

public readonly ReactiveCommand<string> ChangeName;

这是失败的测试:

[Test]
public void ChangeNamePretendsToCallServerButOurTestRunsFast()
{
    (new TestScheduler()).With(sched =>
    {
        var sut = new PersonViewModel {FirstName = "Jane", LastName = "Appleseed"};
        Assert.IsTrue(sut.ChangeName.CanExecute(null));

        sut.ChangeName.ExecuteAsync();

        sched.AdvanceByMs(1000);
        Assert.AreEqual(null, sut.ServerResult);

        sched.AdvanceByMs(10000);
        Assert.AreEqual("Hello World", sut.ServerResult);
    });
}

基本上,我遵循了将命令转换为 RUI6 的指南,但它似乎不起作用。我在任务方法和订阅中设置了一些断点并调试了测试 - 这些断点从未被命中。

【问题讨论】:

    标签: reactiveui


    【解决方案1】:

    这是设计使然:

    // You didn't Subscribe, so it doesn't do anything
    sut.ChangeName.ExecuteAsync();
    

    将其更改为:

    var result = default(string);
    sut.ChangeName.ExecuteAsync().Subscribe(x => result = x);
    
    sched.AdvanceByMs(1000);
    Assert.AreEqual(null, result);
    
    sched.AdvanceByMs(10000);
    Assert.AreEqual("Hello World", result);
    

    【讨论】:

    • 但它不会测试我的视图模型属性在超时后是否发生了变化。另外,我确实订阅了 VM 构造函数 ChangeName.Subscribe(x => ServerResult = x);
    • 您可以将验证结果更改为验证 VM 属性。重要的部分是订阅 ExecuteAsync 结果
    • 我输入了您建议的代码,但测试仍然像以前一样失败。
    • 如果你使用 CreateAsyncObservable 而不是 CreateAsyncTask 会发生什么?
    • 太棒了! 'await' 在内部调用 'Subscribe' 来完成这项工作,所以任何时候你看到 'await' 都知道正在创建一个订阅
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多