2014-08-30 1 views
1

Я создаю приложение с использованием MVVM и ReactiveCocoa для создания привязок между viewModel и пользовательским интерфейсом, однако блок подписки на сигнал подтверждения модели не вызывается.ReactiveCocoa блок подписки, не вызываемый в viewModel в Swift

моего взгляд модель довольно проста и скелетная:

class ViewModel: RVMViewModel { 
    var name: String = "" { 
     willSet { 
      println("New Value: \(newValue)") 
     } 
    } 

    required init(){ 
     super.init() 
     let signal = self.rac_valuesForKeyPath("name", observer: self) 
     signal.subscribeNext { 
      println("Subscribe block: \($0)") 
     } 
    } 
} 

На моем взгляде контроллере, у меня есть следующие привязки:

//observe ui and programatic changes 
RACSignal.merge([self.nameField.racTextSignal(), self.nameField.rac_valuesForKeyPath("text", observer:self)]).subscribeNext({ 
    (next) -> Void in 
    if let text = next as? String { 
     self.viewModel.name = text 
    } 
}) 
RAC(self.nameField, "text") = self.viewModel.rac_valuesForKeyPath("name", observer: self) 

Я получил RAC макрос работает в стриже основой от того, что я читать here.

Теперь, на мой взгляд, привязки в контроллере my view, блоки subscribeNext называются просто отлично. В моем представленииModel, в willSet, выдается новое значение. ОДНАКО, блок подписки на мой сигнал в моем блоке init только вызывается один раз, когда свойство сначала инициализируется. Это подталкивает меня к стене, у кого есть идеи?

ответ

2

Я нашел решение после нескольких экспериментов. Назначая сигнал непосредственно свойству модели представления, блок подписки вызывается каждый раз, когда значение изменяется.

Так вместо того, чтобы сделать это:

RACSignal.merge([self.nameField.racTextSignal(), self.nameField.rac_valuesForKeyPath("text", observer:self)]).subscribeNext({ 
    (next) -> Void in 
    if let text = next as? String { 
     self.viewModel.name = text 
    }  
}) 

Я сделал это:

RAC(self.viewModel, "name") <~ RACSignal.merge([self.nameField.racTextSignal(),  
self.nameField.rac_valuesForKeyPath("text", observer:self)]) 

Я использовал this link, чтобы получить RAC и <~ работать в стрижа.

1

У меня пока нет решения - я далеко от своего ноутбука до вечера. Однако попробуйте сделать сигнал в глобальной области видимости или переменной экземпляра ... Если это не сработает, попробуйте использовать его в одном методе как метод, который вы явно вызываете ... Это больше тестов, но если вы скажете мне, как это происходит, могут работать вместе.

+0

Я закончил тем, что понял это, поэтому не стоит беспокоиться. – barndog

+1

@startupthekid, если вы решили его, пожалуйста, опубликуйте решение, это так ведь, и мы хотели бы поделиться тем, что мы узнаем здесь :) –

0

Лучшее решение, чем тот, который принят, чтобы просто пометить свойство динамической:

dynamic var name: String = "" { 
    willSet { 
     println("New Value: \(newValue)") 
    } 
} 

Это позволяет уровень Obj-C Кво, который, как правило, запрещены для Swift только свойства.

Смежные вопросы