Se eu definir o texto em um NSTextField
programaticamente por meio de -setStringValue:
ou -setAttributedStringValue:
, isso não acionará NSControlTextDidChangeNotification
, o que significa que -rac_textSignal
ganhou não pegue a mudança também. Só funciona quando o texto está sendo editado pela interação do usuário.
A solução fácil seria usar -rac_signalForSelector:
para interceptar chamadas para os setters também (além de registrar NSControlTextDidChangeNotification
). Alguma outra ideia?
A consistência com o AppKit aqui é um recurso, não um bug. Seria estranho, IMO, que rac_textSignal
disparasse para eventos que não são convencionalmente observáveis.
Isso nem sempre faz sentido, mas geralmente os eventos que se propagam para a camada de visualização devem ser considerados "finais". Se você precisar filtrar ou transformá-los antes desse ponto, deve ser feito por meio de um modelo de vista ou algo ao longo dessas linhas.
Qual é o caso de uso para observar mudanças programáticas?
Exemplo específico: Eu tenho um formulário com vários campos de texto e um botão Limpar, clicando em Limpar define stringValue
em cada campo de texto para @""
. Eu uso rac_textSignal
para alguma lógica de validação de formulário, e o status de validação não é atualizado quando Clear é clicado porque -rac_textSignal
não pega as mudanças. A única solução alternativa é postar manualmente NSControlTextDidChangeNotification
, o que é uma coisa horrível de se fazer: trollface:
Em termos de MVVM , o design correto seria executar a validação no _modelo de visão_, não na visão. O modelo de visualização teria ligações bidirecionais para os campos de texto. Então, o botão Limpar pode redefinir os campos do modelo de visualização, e tudo é: brilha :
O MVC seria bastante semelhante, apenas com um controlador ou modelo de visualização intermediário.
Eu havia considerado isso, mas usar ligações é um problema por si só no meu caso particular. Isso é irrelevante para esta questão, no entanto, acho que isso pode ser encerrado. Obrigado!
FWIW, mesmo que Cocoa Bindings ™ seja um problema, você pode usar RACChannel
para construir seus próprios vínculos bidirecionais que não dependem dele.
Sei que está fechado há muito tempo, mas encontrei uma solução para o seu problema @indragiek.
Digamos que você tenha uma propriedade NSString* name
em seu viewModel.
Em seu controlador de visualização, ao vincular o campo de texto ao modelo de visualização e vice-versa, faça o seguinte:
[[RACSignal merge:@[self.nameField.rac_textSignal, RACObserve(self.nameField, text)]]<br i="9"/>
subscribeNext:^(NSString* text){<br i="10"/>
self.viewModel.name = text;<br i="11"/>
}];`
Desta forma, você detecta sempre que o sinal de texto dispara E para alterações programáticas na propriedade do texto.
@startupthekid obrigado, isso ajuda para mim.
@startupthekid muito obrigado!
Comentários muito úteis
Sei que está fechado há muito tempo, mas encontrei uma solução para o seu problema @indragiek.
Digamos que você tenha uma propriedade
NSString* name
em seu viewModel.Em seu controlador de visualização, ao vincular o campo de texto ao modelo de visualização e vice-versa, faça o seguinte:
[[RACSignal merge:@[self.nameField.rac_textSignal, RACObserve(self.nameField, text)]]<br i="9"/> subscribeNext:^(NSString* text){<br i="10"/> self.viewModel.name = text;<br i="11"/> }];`
Desta forma, você detecta sempre que o sinal de texto dispara E para alterações programáticas na propriedade do texto.