如何用Swift实现双向绑定?

时间:2015-11-28 16:10:46

标签: swift2 couchbase-lite

如何使用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属性?

因此,模型中的更改会显示在表单中,反之亦然?

1 个答案:

答案 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文档以获取更多信息。

相关问题