Erste Dinge zuerst. Ihr Beispiel-Code verwendet a text
binding auf einem input
-Knoten, der nicht so nützlich ist (es würde eine One-Way Bindung von Ansicht Modell zu DOM, der "Text" Inhalt dieser input
, die nicht sinnvoll ist). Angesichts der valueUpdate
Bindung Sie wahrscheinlich the value
binding? Beachten Sie übrigens, dass der Weg ist, diese beiden in modernen Versionen von KnockoutJS zu kombinieren.
Was Ihre eigentliche Frage betrifft, fehlen wichtige Kontext: Warum Sie (denken Sie) wollen, dies zu tun? Je nach Kontext ist die Lösung anders, oder Sie haben sogar eine XY-problem.
In jedem Fall zu den Antworten.
Option 1
Der Versuch, dennoch die konkrete Frage zu beantworten, ich zweite @JohnnyHK's answer eines .subscribe
auf beobachtbaren als eine mögliche Lösung zu schreiben.
Option 2
Eine andere mögliche Lösung stark ähnelt, dass ein, sondern versuchen, gerecht zu werden „Ich bin nicht daran interessiert, den Wert des Eingangs“ -Teil, schlage ich mit einem Nur-Lese-beobachtbaren berechnet:
function Root() {
var self = this;
self.filter = ko.computed({
read: function() { return ""; }, // <-- not recommended, read context!
write: function(newValue) {
// You're free to discard the newValue <-- not recommended, read context!
alert("Input has been changed.");
}
});
}
ko.applyBindings(new Root());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="textInput: filter">
Nun ist diese verwirft ausdrücklich die newValue
im Schreib-Bit (wie pro Ihre Anfrage), und damit auch ha s eine seltsam aussehende read
Funktion. Ich empfehle das nicht, und stattdessen würde empfehlen, eine private Variable mit einer beobachtbaren Unterstützung zum Lesen und Schreiben zu verwenden. Effektiv würde dies jedoch diese Option der ersten Option aus der anderen Antwort gleichwertig machen. obwohl
Eine interessante Anmerkung, etwas Ihre Frage ist über „die collectin“ und Filtereingang: wenn man sich the docs from writeable computed
s aussehen werden Sie feststellen, dass die Benutzer Eingabe zu akzeptieren oder nicht, ob es eine bestimmte Bedingung erfüllt ist in der Tat ein Anwendungsfall dafür.
Option 3
Was ich aber empfehlen würde, wenn ich Ihre Anfrage ein wenig anders formulieren:
Wie gehen Sie mit idiomatischen KnockoutJS zu input
value
Änderungen reagieren, wenn Ihre Aktion nicht kümmern sich um die tatsächliche value
?
Zum Schreiben einer benutzerdefinierten Interaktion mit dem DOM gibt es custom binding handlers. Sie können entweder eine verwenden, die das ViewModel überhaupt nicht verwendet, oder eine, die eine Observable hat.
Option 3.A
ko.bindingHandlers["opacitor"] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$(element).on("keydown", function() {
$(this).animate({ opacity: 0.05 }, 1000, function() { $(this).animate({ opacity: 1.0 }, 1000); });
});
}
}
ko.applyBindings({});
input { background-color: gold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="opacitor">
Option 3.B
Oder eine zweite Option, die das View-Modell nicht verwendet:
ko.bindingHandlers["opacitor"] = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
$(element).on("keydown", function() {
var speed = ko.utils.unwrapObservable(valueAccessor)();
$(this).animate({ opacity: 0.05 }, speed, function() { $(this).animate({ opacity: 1.0 }, speed); });
});
}
}
// speed1 and speed2 could also be observables
ko.applyBindings({ speed1: 500, speed2: 2000 });
input { background-color: gold; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="opacitor: speed1">
<input data-bind="opacitor: speed2">
Der Nachteil beider Optionen 3A und 3B ist, dass Sie benutzerdefinierte Ereignisbehandlungslogik schreiben müssen. Wenn Sie einen Blick auf the textInput
source from KO werfen, werden Sie sehen, dass es nicht trivial ist, um diese Dinge korrekt Cross-Browser zu behandeln. Die Verwendung von Option 1 oder 2 könnte also immer noch besser sein (auch wenn Sie eine Interaktion mit dem Ansichtsmodell haben, obwohl "Sie nicht interessiert sind").
Option 4
Verwendung the event
binding. Dies hat die gleichen Nachteile wie Option 3, könnte aber trotzdem eine einfache Lösung sein.Hier ein Beispiel:
function Root(){
var self = this;
self.myFn = function(data, element) {
console.log(element.target.value);
return true;
};
}
ko.applyBindings(new Root());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<input data-bind="event: { keyup: myFn }">
Eine subtile Änderung, die Sie in diesem letzten sehen werden, und eine Frage, die ich beenden möchten mit: hast in dir tatsächlich nicht this issue haben, wo Sie wirklich brauchen der neue Wert und sollte daher nicht auf afterkeydown
betrachten, aber für ein anderes Ereignis?
warum down-vote ohne grund? – pso
Dies funktioniert nicht mit dem Ansichtscode von OP, der eine 'text' Bindung hat. Auch unter der Annahme einer "value" -Bindung wird diese Lösung technisch funktionieren, aber es ist überhaupt kein idiomatischer KnockoutJS, der sich auf einen Nebeneffekt davon verlässt, wie KO intern arbeitet und nach meiner Erfahrung Probleme auf der Straße verursacht. – Jeroen
Aber der Typ hat gesagt "In meinem Szenario bin ich nicht daran interessiert, den Wert der Eingabe an eine Eigenschaft im Viewmodel zu binden." Meine Lösung funktioniert für sein Szenario, glaube ich. – pso