190 votes

Comment puis-je me Knockout JS pour lier des données sur keypress au lieu de la mise au point perdu ?

Cet exemple de knockout js fonctionne ainsi, lorsque vous modifiez un champ et appuyez sur TAB, les données du viewmodel et donc le texte en dessous des champs est mis à jour.

Comment puis-je modifier ce code afin que le viewmodel données sont mis à jour à chaque pression de touche ?

alt text

297voto

Sergei Golos Points 3113
<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>

À partir de la documentation

Des paramètres supplémentaires

  • valueUpdate

    Si votre liaison comprend également un paramètre appelé valueUpdate, ce définit le navigateur d'événements KO à utiliser pour détecter les changements. L' valeurs de chaîne suivantes sont le plus souvent des choix utiles:

    • "le changement" (par défaut) - mises à jour de votre modèle d'affichage lorsque l'utilisateur déplace le focus vers un autre contrôle, ou dans le cas de éléments, immédiatement après toute modification

    • "keyup" - mises à jour de votre modèle d'affichage lorsque l'utilisateur relâche une touche

    • "keypress" - mises à jour de votre modèle d'affichage lorsque l'utilisateur a tapé un clé. Contrairement à keyup, cette mise à jour à plusieurs reprises pendant que l'utilisateur possède une clé en bas

    • "afterkeydown" - mises à jour de votre modèle de vue dès que l'utilisateur commence à taper un caractère. Cela fonctionne par la capture de l'navigateur l'événement keydown et la gestion de l'événement de manière asynchrone.

De ces options, "afterkeydown" est le meilleur choix si vous voulez gardez votre modèle d'affichage mis à jour en temps réel.

85voto

Salvador Dali Points 11667

Dans la version 3.2 , vous pouvez simplement utiliser liaison textinput.:

Pour cela, deux choses importantes :

  • mettre à jour immédiatement
  • différences entre les navigateurs poignées pour couper, faire glisser, saisie semi-automatique...

Donc pas besoin de modules supplémentaires, des contrôles personnalisés et d’autres choses.

35voto

Jeff Mercado Points 42075

Si vous souhaitez faire des mises à jour sur afterkeydown "par défaut", vous pouvez injecter de l' valueUpdate la liaison dans l' value de la liaison de gestionnaire. Il suffit de fournir un nouveau allBindingsAccessor pour le gestionnaire à utiliser qui inclut afterkeydown.

(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
    };
} ());

Si vous n'êtes pas à l'aise "substitution de" l' value de la liaison, vous pouvez donner de la primauté de la coutume de la liaison d'un nom différent et l'utilisation que la liaison de gestionnaire.

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

démo

20voto

RockResolve Points 539

Réponse de Jeff Mercado est fantastique, mais malheureusement cassé avec 3 Knockout.

Mais j’ai trouvé la réponse suggérée par les devs ko alors qu’il travaillait à travers Knockout 3 changements. Voir les commentaires de bas à https://github.com/knockout/knockout/pull/932. Leur code :

http://jsfiddle.net/MBEST/GKJnt/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X