Reactivecocoa: NSControl -rac_textSignal funktioniert beim programmgesteuerten Festlegen von Text nicht

Erstellt am 27. Aug. 2013  ·  8Kommentare  ·  Quelle: ReactiveCocoa/ReactiveCocoa

Wenn ich Text programmgesteuert über -setStringValue: oder -setAttributedStringValue: auf ein NSTextField setze, löst dies nicht NSControlTextDidChangeNotification , was bedeutet, dass -rac_textSignal gewonnen hat Ich nehme das Wechselgeld auch nicht auf. Dies funktioniert nur, wenn der Text durch Benutzerinteraktion bearbeitet wird.

Eine einfache Lösung wäre, -rac_signalForSelector: zu verwenden, um Anrufe an die Setter abzufangen (zusätzlich zur Registrierung für NSControlTextDidChangeNotification ). Irgendwelche anderen Ideen?

question

Hilfreichster Kommentar

Ich weiß, dass dies schon lange geschlossen ist, aber ich habe eine Lösung für Ihr Problem @indragiek gefunden.
Angenommen, Sie haben eine Eigenschaft, NSString* name in Ihrem viewModel.
Wenn Sie in Ihrem Ansichts-Controller das Textfeld an das Ansichtsmodell binden und umgekehrt, gehen Sie folgendermaßen vor:
[[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"/> }];`

Auf diese Weise erkennen Sie, wann immer das Textsignal ausgelöst wird UND für programmatische Änderungen an der Texteigenschaft.

Alle 8 Kommentare

Die Konsistenz mit AppKit ist hier eine Funktion, kein Fehler. Es wäre seltsam, IMO, wenn rac_textSignal für Ereignisse ausgelöst würde, die konventionell nicht beobachtbar sind.

Dies ist nicht immer sinnvoll, aber im Allgemeinen sollten Ereignisse, die sich auf die Ansichtsebene ausbreiten, als "endgültig" betrachtet werden. Wenn Sie sie vor diesem Punkt filtern oder transformieren müssen, sollte dies über ein Ansichtsmodell oder etwas in dieser Richtung erfolgen.

Was ist der Anwendungsfall für die Beobachtung programmatischer Änderungen?

Spezifisches Beispiel: Ich habe ein Formular mit mehreren Textfeldern und einer Schaltfläche Löschen. Wenn Sie auf Löschen klicken, wird stringValue für jedes Textfeld auf @"" . Ich verwende rac_textSignal für eine Formularvalidierungslogik, und der Validierungsstatus wird nicht aktualisiert, wenn auf Löschen geklickt wird, da -rac_textSignal die Änderungen nicht übernimmt. Die einzige Problemumgehung besteht darin, NSControlTextDidChangeNotification manuell zu posten, was eine schreckliche Sache ist: trollface:

In Bezug auf MVVM wäre das richtige Design, eine Validierung für das Ansichtsmodell durchzuführen, nicht für die Ansicht. Das Ansichtsmodell hätte bidirektionale Bindungen zu den Textfeldern. Dann kann die Schaltfläche Löschen die Felder des Ansichtsmodells zurücksetzen, und alles ist: funkelt:.

MVC wäre ziemlich ähnlich, nur mit einem Intermediär-View-Controller oder -Modell.

Ich hatte darüber nachgedacht, aber die Verwendung von Bindungen ist in meinem speziellen Fall ein Problem für sich. Das ist jedoch für diese Frage irrelevant, daher denke ich, dass dies geschlossen werden kann. Vielen Dank!

FWIW, auch wenn Cocoa Bindings ™ ein Problem darstellt, können Sie mit RACChannel Ihre eigenen bidirektionalen Bindungen erstellen, die nicht davon abhängig sind.

Ich weiß, dass dies schon lange geschlossen ist, aber ich habe eine Lösung für Ihr Problem @indragiek gefunden.
Angenommen, Sie haben eine Eigenschaft, NSString* name in Ihrem viewModel.
Wenn Sie in Ihrem Ansichts-Controller das Textfeld an das Ansichtsmodell binden und umgekehrt, gehen Sie folgendermaßen vor:
[[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"/> }];`

Auf diese Weise erkennen Sie, wann immer das Textsignal ausgelöst wird UND für programmatische Änderungen an der Texteigenschaft.

@startupthekid danke, es hilft mir.

@startupthekid vielen Dank!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen