Как реализовать двухстороннее связывание со Swift?

Как реализовать двухстороннее связывание данных с помощью 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 ответ

Решение

Swift не поддерживает привязки из коробки, но вы можете достичь их с помощью таких фреймворков, как ReactiveKit.

Например, когда вы объявляете наблюдаемое свойство, вы можете связать его с другим наблюдаемым свойством.

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

numberA.bindTo(numberB)

Чтобы сделать двунаправленный, просто свяжите в другом направлении:

numberB.bindTo(numberA)

Теперь, когда вы меняете один из них, другой изменится.

Ваш пример немного сложнее, потому что вам нужно делать привязки из свойств @NSManaged, которые нельзя сделать Observable, Это не невозможно, но для работы свойства Person должны поддерживать наблюдение значения ключа (KVO).

Например, учитывая объект Person и метку, вы можете получить свойство из свойства с включенным KVO с помощью метода 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 имеет тип Any?, Вы должны переосмыслить это и посмотреть, сможете ли вы сделать его более сильным.

Обратите внимание, что привязки UIKit поступают из платформы ReactiveUIKit. Проверьте нашу документацию ReactiveKit для получения дополнительной информации.

Другие вопросы по тегам