如何用Swift实现双向绑定?

Mar*_*art 2 couchbase-lite swift2

如何使用Swift 2.0实现双向数据绑定?

假设我有以下模型类(使用couchbase lite):

@objc(Person)
class Person: NSObject{
    @NSManaged var firstName: NSString?
    @NSManaged var lastName: NSString?
}
Run Code Online (Sandbox Code Playgroud)

我喜欢将属性绑定到给定的formItemDescriptor,如下所示:

class FormItemDescriptor {
    var tag: String?
    var value: Any?
}
Run Code Online (Sandbox Code Playgroud)

如何使用双向绑定将FormItemDescriptor.value属性绑定到属性Person.firstName

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

Srđ*_*đan 5

Swift不支持开箱即用的绑定,但你可以使用像ReactiveKit这样的框架来实现它们.

例如,当您声明一个observable属性时,您可以将其绑定到另一个可观察属性.

let numberA: Property<Int>
let numberB: Property<Int>

numberA.bindTo(numberB)
Run Code Online (Sandbox Code Playgroud)

要做双向,也要在其他方向绑定:

numberB.bindTo(numberA)
Run Code Online (Sandbox Code Playgroud)

现在,每当你改变其中任何一个时,另一个都会改变.

你的例子有点困难,因为你需要从无法制作的@NSManaged属性进行绑定Observable.这并非不可能,但是为了工作,Person的属性应该支持键值观察(KVO).

例如,给定一个Person对象和一个标签,您可以使用该方法从KVO-enabled属性中获取一个Property rValueForKeyPath,然后将该observable绑定到该标签,如下所示:

let person: Person
let nameLabel: UILabel

person.rValueForKeyPath("firstName").bindTo(nameLabel)
Run Code Online (Sandbox Code Playgroud)

如果你有像你这样的中间对象FormItemDescriptor,那么你必须使其属性可观察.

class FormItemDescriptor {
  var tag: Property<String?>
  var value: Property<Any?>
}
Run Code Online (Sandbox Code Playgroud)

现在你可以建立绑定

let person: Person
let descriptor: FormItemDescriptor

person.rValueForKeyPath("firstName").bindTo(descriptor.value)
Run Code Online (Sandbox Code Playgroud)

因为firstName不可观察,所以不能在另一个方向上进行绑定,因此每次value更改时都必须手动更新.

descriptor.value.observeNext { value in
  person.firstName = value as? NSString
}
Run Code Online (Sandbox Code Playgroud)

我们还必须做演员,NSString因为value是类型Any?.你应该重新考虑一下,看看你是否可以把它变成一个更强大的类型.

请注意,UIKit绑定来自ReactiveUIKit框架.有关详细信息,请查看我们的ReactiveKit文档.