如何使用Swift 2.0实现双向数据绑定?
假设我有以下模型类(使用couchbase lite):
@objc(Person)
class Person: NSObject{
@NSManaged var firstName: NSString?
@NSManaged var lastName: NSString?
}
我喜欢将属性绑定到给定的formItemDescriptor,如下所示:
class FormItemDescriptor {
var tag: String?
var value: Any?
}
如何使用双向绑定将FormItemDescriptor.value
属性绑定到Person.firstName
属性?
因此,模型中的更改会显示在表单中,反之亦然?
答案 0 :(得分:5)
Swift不支持开箱即用的绑定,但您可以使用ReactiveKit等框架来实现它们。
例如,当您声明一个可观察的属性时,您可以将其绑定到另一个可观察的属性。
let numberA: Property<Int>
let numberB: Property<Int>
numberA.bindTo(numberB)
要做双向,也要在其他方向绑定:
numberB.bindTo(numberA)
现在,每当你改变其中任何一个时,另一个都会改变。
您的示例有点困难,因为您需要从无法生成{@ 1}}的@NSManaged属性进行绑定。这并非不可能,但是为了工作,Person的属性应该支持键值观察(KVO)。
例如,给定Person对象和标签,您可以使用方法Observable
从KVO-enabled属性获取Property,然后将该observable绑定到标签,如下所示:
rValueForKeyPath
如果您有像let person: Person
let nameLabel: UILabel
person.rValueForKeyPath("firstName").bindTo(nameLabel)
这样的中间对象,那么您必须使其属性可观察。
FormItemDescriptor
现在你可以建立绑定
class FormItemDescriptor {
var tag: Property<String?>
var value: Property<Any?>
}
由于let person: Person
let descriptor: FormItemDescriptor
person.rValueForKeyPath("firstName").bindTo(descriptor.value)
无法观察,因此您无法在其他方向进行绑定,因此每当firstName
更改时,您都必须手动更新它。
value
由于descriptor.value.observeNext { value in
person.firstName = value as? NSString
}
的类型为NSString
,因此我们还必须执行转换为value
。你应该重新考虑一下,看看你是否可以把它变成一个更强大的类型。
请注意,UIKit绑定来自ReactiveUIKit框架。查看我们的ReactiveKit文档以获取更多信息。