我经常在我想要一个UI元素,以“看”的潜在价值的情况 - 假如我展示一个int - 我要一个一个的IObservable我可以订阅。
我一直在使用一个主题之下,这样我就可以设置它。这一工程真的很好......除了第一次。如果我设置的主题 - 后来订阅它打开一个新的UI元素 - 它不会触发onnext直到下一个变化。
基本上,我想要的东西,就像一个主题 - 但始终并立即做了最新价值的任何新用户的onNext。
我知道我可以写这样的构建自己 - 但它似乎是一个常见的情况 - 是有什么标准,我失踪?
你想要么BehaviorSubject<T>
或ReplaySubject<T>
。
BehaviorSubject<T>
重放单个最近的值,并要求你给在构造函数中的初始值。
您可以使用这样的:
var bs = new BehaviorSubject<int>(0);
bs.Subscribe(x => Console.WriteLine(x));
bs.OnNext(42);
bs.Subscribe(x => Console.WriteLine(x));
这将输出0
,然后42
,然后42
到控制台。
ReplaySubject<T>
是一个小更普遍。它允许你指定值重播的数量,但并不强制你提供一个初始值。
var rs = new ReplaySubject<int>(1);
rs.Subscribe(x => Console.WriteLine(x));
rs.OnNext(42);
rs.Subscribe(x => Console.WriteLine(x));
这将产生42
,然后42
到控制台。
与此相比,一个标准Subject<T>
。
var s = new Subject<int>();
s.Subscribe(x => Console.WriteLine(x));
s.OnNext(42);
s.Subscribe(x => Console.WriteLine(x));
这只是生产42
。
如果您在使用UI的Rx,你应该看一看ReactiveUI。
它具有方便的扩展.ToProperty
多:
_isValid = this.WhenAnyValue(x => x.Username, x => x.Password, (user, password) => !string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password)).ToProperty(this, x => x.IsValid);
public bool IsValid => _isValid.Value;
这基本上是你在做什么:
this.WhenAnyValue(x => x.Property)
=>属性如可观察到的obs.ToProperty()
=>可观察到可以绑定到UI属性都与INotifyPropertyChanged
工作