ToProperty和BindTo - 获取初始值而订阅 [英] ToProperty and BindTo - Get initial value without Subscribing

查看:134
本文介绍了ToProperty和BindTo - 获取初始值而订阅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在.NET 4.5使用RXUI 6 WPF。

我一直有麻烦提供给我的视图的初始值时,视图模型属性就必然是由一个支持 ObservableAsPropertyHelper

根据<一href=\"https://github.com/reactiveui/ReactiveUI/blob/master/docs/migrating-from-rxui5.md#toproperty--oaph-changes\"相对=nofollow>文档:


  

ToProperty / OAPH变化


  
  

      
  • ObservableAsPropertyHelper不再本身就是一个的IObservable,使用WhenAny来观察它。


  •   
  • ObservableAsPropertyHelper现在懒惰地预订仅当读出值首次源。这显著结果
      提高性能和内存使用情况,但某些为什么结果成本
      没有我的测试工作?的困惑。如果你发现你的ToProperty结果
      不工作,这可能是为什么。


  •   

我看了<一个href=\"http://stackoverflow.com/questions/22432822/observableaspropertyhelper-have-to-access-value-to-get-it-to-subscribe\">this问题似乎要解决我同样的问题,但答案在测试和使用 ReactiveCommand 提供作品。我想不出最清洁的方式来获得这在我与任何的IObservable&LT的情况下工作;&GT; 不一定 ReactiveCommand (以下简单化了)。

例视图模型:

 公共类视图模型:ReactiveObject
{
    私人只读ObservableAsPropertyHelper&LT;串GT; _信息;    公共视图模型()
    {
       VAR someObservable = Observable.Return(你好);        _message = someObservable
            .ToProperty(这一点,T =&GT; t.Message);
    }    公共字符串消息
    {
        得到
        {
            返回_message.Value;
        }
    }
}

查看示例code-背后:

 公共部分类查看:用户控件,IViewFor&LT;视图模型&GT;
{
     公共查看()
     {
        的InitializeComponent();        this.WhenAnyValue(T =&GT; t.ViewModel.Message)
            .BindTo(这一点,T =&GT; t.MessageTextBlock.Text);
     }
     // ... IViewFor东西....
}

所以现在,消息文本框将不包含在初始值。但是,如果在我的ViewModel我是行添加到构造器:

  this.WhenAnyValue(T =&GT; t.Message).Subscribe(S = GT; {});

现在将火关到TextBlock,因为现在有一个订阅。所以我猜测,在 .BindTo()方法从来没有真正算作订阅?或者是懒惰的顶部懒惰?这是否为空订阅否定从中懒惰的性能优势?或者我应该不会使用 .BindTo()键,只需要使用 .Subscribe()来分配TextBlock的?

**编辑**
好了,有可能是别的东西在我的code回事,因为我一直没能始终如一地重现此问题。如果我找到问题的根源,我会汇报。

*编辑2 *
我已经确认我在这是造成哑火,而不是OAPH另一个问题。该.ToProperty和.BindTo似乎像现在预计将始终如一地工作。谢谢你。


解决方案

  

现在将火关到TextBlock,因为现在有一个订阅。所以我猜的.BindTo()方法从来没有真正算作一个订阅?


BindTo立即订阅源,应揭开序幕OAPH。然而,这种认购事项将不会真正的发生的直到视图获取一个视图模型:

  //无法订阅(空).Message!
this.WhenAnyValue(T =&GT; t.ViewModel.Message)

I'm using RXUI 6 with WPF in .NET 4.5.

I've been having trouble getting an initial value provided to my View when the ViewModel property it is bound to is backed by an ObservableAsPropertyHelper.

According to the documentation:

ToProperty / OAPH changes

  • ObservableAsPropertyHelper no longer is itself an IObservable, use WhenAny to observe it.

  • ObservableAsPropertyHelper now lazily Subscribes to the source only when the Value is read for the first time. This significantly
    improves performance and memory usage, but at the cost of some "Why
    doesn't my test work??" confusion. If you find that your ToProperty
    "isn't working", this may be why.

I looked at this question which seems to address my same problem, but the answer provided works in testing and with a ReactiveCommand. I cannot figure out the cleanest way to get this to work in my situation with any IObservable<> not necessarily a ReactiveCommand (oversimplified below).

Example ViewModel:

public class ViewModel : ReactiveObject
{
    private readonly ObservableAsPropertyHelper<string> _message;

    public ViewModel()
    {
       var someObservable = Observable.Return("Hello");

        _message = someObservable
            .ToProperty(this, t => t.Message);
    }

    public string Message
    {
        get
        {
            return _message.Value;
        }
    }
}

Example View Code-behind:

public partial class View : UserControl, IViewFor<ViewModel>
{
     public View()
     {
        InitializeComponent();

        this.WhenAnyValue(t => t.ViewModel.Message)
            .BindTo(this, t => t.MessageTextBlock.Text);
     }
     // ... IViewFor Stuff....
}

So right now, the Message TextBox will not contain the initial value. However if in my ViewModel I was to add the line to the contructor:

this.WhenAnyValue(t => t.Message).Subscribe(s => {});

It will now fire off to the TextBlock because now there is a subscription. So I'm guessing that the .BindTo() method never actually counts as a subscription? Or it is laziness on top of laziness? Does this empty subscription negate the performance benefits from it being lazy? Or should I not use .BindTo() and just use a .Subscribe() to assign the TextBlock?

** EDIT ** Ok, there might be something else going on in my code as I have not been able to reproduce this behavior consistently. I will report back if I find the root cause.

* EDIT 2 * I have confirmed that I had another issue that was causing the misfiring, not OAPH. The .ToProperty and .BindTo seem to be working consistently as expected now. Thanks.

解决方案

It will now fire off to the TextBlock because now there is a subscription. So I'm guessing that the .BindTo() method never actually counts as a subscription?

BindTo immediately Subscribes to the source and should kick off the OAPH. However, this Subscription won't actually happen until the View gets a ViewModel:

// Can't subscribe to (null).Message!
this.WhenAnyValue(t => t.ViewModel.Message)

这篇关于ToProperty和BindTo - 获取初始值而订阅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆