Si je place du texte sur un NSTextField
par programme via -setStringValue:
ou -setAttributedStringValue:
, cela ne déclenche pas NSControlTextDidChangeNotification
, ce qui signifie que -rac_textSignal
gagné Je ne prends pas la monnaie non plus. Cela ne fonctionne que lorsque le texte est en cours d'édition par interaction de l'utilisateur.
Une solution simple serait d'utiliser -rac_signalForSelector:
pour intercepter également les appels aux setters (en plus de vous inscrire pour NSControlTextDidChangeNotification
). D'autres idées?
La cohérence avec AppKit ici est une fonctionnalité, pas un bogue. Ce serait bizarre, OMI, que rac_textSignal
se déclenche pour des événements qui ne sont pas observables par convention.
Cela n'a pas toujours de sens, mais en général, les événements qui se propagent à la couche de vue doivent être considérés comme «finaux». Si vous avez besoin de les filtrer ou de les transformer avant ce point, cela doit être fait via un modèle de vue ou quelque chose du genre.
Quel est le cas d'utilisation de l'observation des changements programmatiques?
Exemple spécifique: j'ai un formulaire avec plusieurs champs de texte et un bouton Effacer, cliquer sur Effacer définit stringValue
sur chaque champ de texte à @""
. J'utilise rac_textSignal
pour une logique de validation de formulaire, et l'état de validation n'est pas mis à jour lorsque vous cliquez sur Effacer car -rac_textSignal
ne prend pas en compte les modifications. La seule solution de contournement est de publier manuellement NSControlTextDidChangeNotification
, ce qui est une chose horrible à faire: trollface:
En termes de MVVM , la conception correcte serait d'effectuer une validation sur le _ modèle de vue_, pas sur la vue. Le modèle de vue aurait des liaisons bidirectionnelles avec les champs de texte. Ensuite, le bouton Effacer peut réinitialiser les champs du modèle de vue, et tout est: sparkles :.
MVC serait assez similaire, juste avec un contrôleur de vue intermédiaire ou un modèle à la place.
J'avais pensé à cela, mais l'utilisation de liaisons est un problème en soi dans mon cas particulier. Cela n'a pas de rapport avec cette question, cependant, je pense que cela peut être clos. Merci!
FWIW, même si Cocoa Bindings ™ est un problème, vous pouvez utiliser RACChannel
pour créer vos propres liaisons bidirectionnelles qui n'en dépendent pas.
Je sais que cela est fermé depuis longtemps, mais j'ai trouvé une solution à votre problème @indragiek.
Supposons que vous ayez une propriété, NSString* name
sur votre viewModel.
Dans votre contrôleur de vue, lors de la liaison du champ de texte au modèle de vue et vice versa, procédez comme suit:
[[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"/>
}];`
De cette façon, vous détectez chaque fois que le signal de texte se déclenche ET pour les modifications programmatiques de la propriété de texte.
@startupthekid merci, ça m'aide.
@startupthekid merci beaucoup!
Commentaire le plus utile
Je sais que cela est fermé depuis longtemps, mais j'ai trouvé une solution à votre problème @indragiek.
Supposons que vous ayez une propriété,
NSString* name
sur votre viewModel.Dans votre contrôleur de vue, lors de la liaison du champ de texte au modèle de vue et vice versa, procédez comme suit:
[[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"/> }];`
De cette façon, vous détectez chaque fois que le signal de texte se déclenche ET pour les modifications programmatiques de la propriété de texte.