RX 中是否存在只读的 BehaviorSubject 接口?如果不存在,那么创建一个是不是一个坏主意?
Does a read only BehaviorSubject interface exist in RX and if not, is it a bad idea to make one?
rx 的实现提供 BehaviorSubject<T>
和 Variable<T>
作为随时间变化的建模属性的机制(C# INotifyPropertyChanged 的有用替代品)。
通常这些会公开为 Observable<T>
但将属性公开为以下内容会更有用:
class ObservableValue<T> : Observable<T>{
var currentValue:T { get }
}
可以按照 swift 中的这些行创建:
class ObservableValue<Element> : ObservableType {
typealias E = Element
private let subject:BehaviorSubject<E>
var currentValue:E {
get {
return try! subject.value()
}
}
init(subject:BehaviorSubject<E>) {
self.subject = subject
}
func subscribe<O: ObserverType where O.E == E>(observer: O) -> Disposable {
return self.subject.subscribe(observer)
}
}
这已经存在了吗?如果不是,是因为它违背了 Rx 的目标吗?
解决它的唯一方法是公开一个单独的 currentValue 或编写消费者,假设公开的 Observable 背后的具体实现是 BehaviourSubject 或链中某处发生了 replay(),例如以下代码段并未明确表示,一旦我订阅,我将获得一个值:
class MyViewModel {
// 'I will notify you of changes perhaps including my current value'
myProperty:Observable<String>
}
所以代码必须像 'asynchronous' 一样编写,并有一个基本假设,它将以几乎同步的方式运行,而不是:
class MyViewModel {
// 'I have a current value and will notify you of changes going forward'
myProperty:ObservableValue<String>
}
经过深思熟虑并进一步讨论,它不存在(也许不应该存在)的原因可能是它引入了强制访问状态。
其他维护状态的机制(例如 scan
)在链式可观察对象的范围内进行,而不是 'dead-end' 直接调用,例如 'give me the value right now'.
也许它会放在混合 reactive/imperative 方法中,但它可能只会阻碍对反应式风格的全面接受。
这类似于在一半代码中使用 promises 或任务,然后在其他部分恢复为同步阻塞代码。
在大多数情况下,人们所做的是创建一个标准视图模型,通过 INotifyPropertyChanged 公开属性。这允许 UI 元素绑定到它们并接收 属性 更改事件并保持 UI 同步。
然后,如果您想要一个 IObservable 用于上述 属性,您可以利用标准 Rx 运算符将事件转换为 IObservable。您可以 google 找到许多不同的实现。您通常会从观察视图模型的对象中创建和使用这些可观察对象,而不是直接在视图模型上公开它们。
rx 的实现提供 BehaviorSubject<T>
和 Variable<T>
作为随时间变化的建模属性的机制(C# INotifyPropertyChanged 的有用替代品)。
通常这些会公开为 Observable<T>
但将属性公开为以下内容会更有用:
class ObservableValue<T> : Observable<T>{
var currentValue:T { get }
}
可以按照 swift 中的这些行创建:
class ObservableValue<Element> : ObservableType {
typealias E = Element
private let subject:BehaviorSubject<E>
var currentValue:E {
get {
return try! subject.value()
}
}
init(subject:BehaviorSubject<E>) {
self.subject = subject
}
func subscribe<O: ObserverType where O.E == E>(observer: O) -> Disposable {
return self.subject.subscribe(observer)
}
}
这已经存在了吗?如果不是,是因为它违背了 Rx 的目标吗?
解决它的唯一方法是公开一个单独的 currentValue 或编写消费者,假设公开的 Observable 背后的具体实现是 BehaviourSubject 或链中某处发生了 replay(),例如以下代码段并未明确表示,一旦我订阅,我将获得一个值:
class MyViewModel {
// 'I will notify you of changes perhaps including my current value'
myProperty:Observable<String>
}
所以代码必须像 'asynchronous' 一样编写,并有一个基本假设,它将以几乎同步的方式运行,而不是:
class MyViewModel {
// 'I have a current value and will notify you of changes going forward'
myProperty:ObservableValue<String>
}
经过深思熟虑并进一步讨论,它不存在(也许不应该存在)的原因可能是它引入了强制访问状态。
其他维护状态的机制(例如 scan
)在链式可观察对象的范围内进行,而不是 'dead-end' 直接调用,例如 'give me the value right now'.
也许它会放在混合 reactive/imperative 方法中,但它可能只会阻碍对反应式风格的全面接受。
这类似于在一半代码中使用 promises 或任务,然后在其他部分恢复为同步阻塞代码。
在大多数情况下,人们所做的是创建一个标准视图模型,通过 INotifyPropertyChanged 公开属性。这允许 UI 元素绑定到它们并接收 属性 更改事件并保持 UI 同步。
然后,如果您想要一个 IObservable 用于上述 属性,您可以利用标准 Rx 运算符将事件转换为 IObservable。您可以 google 找到许多不同的实现。您通常会从观察视图模型的对象中创建和使用这些可观察对象,而不是直接在视图模型上公开它们。