如何使用函数式 reactiveSwift 从属性中泛化表单输入?



当我经常做更改时,我想发送的字段

let initialOrChangedName = Signal.merge(
nameChanged.signal, 
self.viewDidLoadProperty.signal
.map { _ in nil }  
)

哪里

private let nameChangedProperty = MutableProperty<String?>(nil)
private let viewDidLoadProperty = MutableProperty(())

获取在加载时触发一次的信号,因此当用户点击一个按钮时,我可以在组合中使用它,该按钮将触发具有表单值的 Web 请求到服务器。由于此信号合并,它将给出在初始值之后更改的所有值,从而允许我在用户点击提交按钮时发送最新值

对此的用法通常是这样的

Signal.combineLatest(intialOrChangedName, initialOrChangedAge)
.sample(on:sendButtonTappedProperty.signal)

如果发送的值为 nil,我只是不将它们包含在 Web 请求中,但如果其中一些值被用户更改,我确实会得到其他值。

由于这是一个相当常见的模式,我想将其推广到单个函数,例如

let initialOrChangedName = nameChanged.initialOrChangedState(on: viewDidLoadProperty)

我试过写它

extension MutableProperty where Value: OptionalProtocol {

public func initialOrChangedState(on viewDidLoadProperty: MutableProperty<Void>) -> Signal<Value?, Error> {
return Signal.merge(self.signal.map(Optional.init),
viewDidLoadProperty.signal.map { _ in nil})
}
}

在纸上看起来不错,但会返回 String?? 对于给出的示例,并且不起作用。

我也尝试过在 Signal 上将其编写为静态函数,但没有运气。

我想应该是这样的:

extension MutableProperty where Value: OptionalProtocol {

public func initialOrChangedState(on viewDidLoadProperty: MutableProperty<Void>) -> Signal<Value?, Error> {
return self.signal.map({Optional<Value>($0)}).merge(with: viewDidLoadProperty.signal.map({_ in nil}))
}
}

但是,使用viewDidLoadProperty有什么意义呢?实际上,如果你在viewDidLoad((结束时订阅你的信号,你甚至不需要这样的属性,因此你不需要那个merge((的东西,你也不需要扩展MutableProperty协议。

因此,您需要做的就是:

submitButton.reactive.controlEvents(.touchUpInside).observer(on: UIScheduler()).observeValues({ _ in
readInputs()
launchRequest()
})

我可能误会了,所以如果我是,请原谅我。但我认为这样的事情可能会有所帮助。我在我编写的库中有这种方法。

public func to<T>(_ value: T) -> Signal<T, Error> {
self.map { _ in value }
}

这允许你做这样的事情

let voidProperty = MutableProperty(())
let nilStringSignal: Signal<String?, Never> = voidProperty.signal.to(nil)

所以也许你的情况可能是这样的,它有点依赖于类型推断

nameChanged.signal.merge(with: self.viewDidLoadProperty.signal.to(nil))

我知道也许这并不像你想要的那么简洁。在信号中使用诸如 optional( 之类的泛型有时会使类型争吵有点令人😅沮丧

相关内容

  • 没有找到相关文章

最新更新