Wie kann ich Knockout JS Daten-bind auf Tastendruck statt verlorenem Fokus bekommen?

StackOverflow https://stackoverflow.com/questions/4386311

  •  10-10-2019
  •  | 
  •  

Frage

In diesem Beispiel wird der Knockout js funktioniert so, wenn Sie ein Feld und drücken Sie TAB bearbeiten, die Viewmodel Daten und damit den Text unterhalb der Felder aktualisiert wird.

Wie kann ich diesen Code ändern, so dass die Daten jedes Ansichtsmodell keypress aktualisiert werden?

alt text

<!doctype html>
<html>
    <title>knockout js</title>
    <head>
        <script type="text/javascript" src="js/knockout-1.1.1.debug.js"></script>
        <script type="text/javascript">
        window.onload= function() {

            var viewModel = {
                firstName : ko.observable("Jim"),
                lastName : ko.observable("Smith")
            };
            viewModel.fullName = ko.dependentObservable(function () {
                return viewModel.firstName() + " " + viewModel.lastName();
            });

            ko.applyBindings(viewModel);
       }
        </script>
    </head>
    <body>
        <p>First name: <input data-bind="value: firstName" /></p>
        <p>Last name: <input data-bind="value: lastName" /></p>
        <h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
    </body>
</html>
War es hilfreich?

Lösung

<body>
        <p>First name: <input data-bind="value: firstName, valueUpdate: 'afterkeydown'" /></p>
        <p>Last name: <input data-bind="value: lastName, valueUpdate: 'afterkeydown'" /></p>
        <h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
</body>

Von der Dokumentation

Zusätzliche Parameter

  • valueUpdate

    Wenn Sie Ihre Bindung enthält auch einen Parameter valueUpdate genannt, diese Ereignis KO definiert, welche Browser sollten Änderungen erkennen verwenden. Das folgende String-Werte sind die am häufigsten nützlichen Möglichkeiten:

    • "change" (default) - aktualisiert die Ansicht Modell, wenn der Benutzer bewegt, um den Fokus auf eine andere Steuerung oder im Fall von Elemente, unmittelbar nach jeder Änderung

    • "keyup" - aktualisiert die Ansicht Modell, wenn der Benutzer eine Taste

    • „keypress“ - aktualisiert die Ansicht Modell, wenn der Benutzer getippt ein Schlüssel. Im Gegensatz zu keyup, aktualisiert diese wiederholt, während der Benutzer einen Schlüssel hält nach unten

    • „afterkeydown“ - aktualisiert die Ansicht Modell, sobald der Benutzer beginnt ein Zeichen eingeben. Dies funktioniert, indem Sie die Browser-Fang keydown Ereignis und das Ereignis asynchron Handhabung.

Von diesen Optionen „afterkeydown“ ist die beste Wahl, wenn Sie wollen Halten Sie Ihr View-Modell in Echtzeit aktualisiert.

Andere Tipps

In Version 3.2 Sie können einfach verwenden TextInput- verbindlich. :

<input data-bind="textInput: userName" />

Es tut zwei wichtige Dinge:

  • macht sofortiges Updates
  • Griffe Browser Unterschiede für Schnitt, ziehen, die automatische Vervollständigung ...

So keine Notwendigkeit für zusätzliche Module, benutzerdefinierte Steuerelemente und andere Dinge.

Wenn Sie es wünschen Updates auf afterkeydown zu tun „standardmäßig“ Sie könnten die valueUpdate Bindung in value Bindung Handler injizieren. liefern nur einen neuen allBindingsAccessor für den Handler zu verwenden, die afterkeydown enthält.

(function () {
    var valueHandler = ko.bindingHandlers.value;
    var getInjectValueUpdate = function (allBindingsAccessor) {
        var AFTERKEYDOWN = 'afterkeydown';
        return function () {
            var allBindings = ko.utils.extend({}, allBindingsAccessor()),
                valueUpdate = allBindings.valueUpdate;

            if (valueUpdate === undefined) {
                return ko.utils.extend(allBindings, { valueUpdate: AFTERKEYDOWN });
            } else if (typeof valueUpdate === 'string' && valueUpdate !== AFTERKEYDOWN) {
                return ko.utils.extend(allBindings, { valueUpdate: [valueUpdate, AFTERKEYDOWN] });
            } else if (typeof valueUpdate === 'array' && ko.utils.arrayIndexOf(valueUpdate, AFTERKEYDOWN) === -1) {
                valueUpdate = ko.utils.arrayPushAll([AFTERKEYDOWN], valueUpdate);
                return ko.utils.extend(allBindings, {valueUpdate: valueUpdate});
            }
            return allBindings;
        };
    };
    ko.bindingHandlers.value = {
        // only needed for init
        'init': function (element, valueAccessor, allBindingsAccessor) {
            allBindingsAccessor = getInjectValueUpdate(allBindingsAccessor);
            return valueHandler.init(element, valueAccessor, allBindingsAccessor);
        },
        'update': valueHandler.update
    };
} ());

Wenn Sie nicht vertraut sind „zwingende“ die value Bindung, könnten Sie die zwingende individuelle geben Sie einen anderen Namen und Verwendung Bindung, die Bindung Handler.

ko.bindingHandlers.realtimeValue = { 'init':..., 'update':... };

Demo

Eine Lösung wie diese würde für Knockout-Version 2.x. geeignet sein Die Knockout-Team hat konkretisiert eine vollständigere Bindung für textartige Eingaben über die textinput Bindung in Knockout-Version 3 und oben. Es wurde entwickelt, um alle Texteingabemethoden für Texteingaben und textarea zu handhaben. Es wird sogar Echtzeit-Aktualisierung handhaben, die effektiv diese Methode obsolet macht.

Jeff Mercado Antwort ist fantastisch, aber leider kaputt mit Knockout 3.

Aber ich fand die Antwort von dem ko Devs vorgeschlagen, während sie durch Änderungen Knockout 3 arbeiten. Sehen Sie sich die unten Kommentare unter https://github.com/knockout/knockout/pull/932. Deren Code:

//automatically add valueUpdate="afterkeydown" on every value binding
(function () {
    var getInjectValueUpdate = function (allBindings) {
        return {
            has: function (bindingKey) {
                return (bindingKey == 'valueUpdate') || allBindings.has(bindingKey);
            },
            get: function (bindingKey) {
                var binding = allBindings.get(bindingKey);
                if (bindingKey == 'valueUpdate') {
                    binding = binding ? [].concat(binding, 'afterkeydown') : 'afterkeydown';
                }
                return binding;
            }
        };
    };

    var valueInitHandler = ko.bindingHandlers.value.init;
    ko.bindingHandlers.value.init = function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        return valueInitHandler(element, valueAccessor, getInjectValueUpdate(allBindings), viewModel, bindingContext);
    };
}());

http://jsfiddle.net/mbest/GKJnt/

Bearbeiten Ko 3.2.0 hat jetzt eine komplette Lösung mit der neuen „textinput“ Bindung. Siehe SalvidorDali Antwort

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top