Comment puis-je obtenir Knockout JS aux données bind au lieu de à chaque touche de mise au point perdu?

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

  •  10-10-2019
  •  | 
  •  

Question

Cet exemple de travaux knock-out js donc lorsque vous modifiez un champ et appuyez sur TAB, les données de viewmodel et par conséquent le texte en dessous des champs est mis à jour.

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

text alt

 
<!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>
Était-ce utile?

La solution

<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>

De la documentation

  

Paramètres supplémentaires

     
      
  • valueUpdate

         

    Si votre fixation comprend également un paramètre appelé valueUpdate, cette   définit quel événement KO navigateur doit utiliser pour détecter les changements. le   suivantes valeurs de chaîne sont les choix les plus souvent utiles:

         
        
    • « changement » (par défaut) - met à jour votre modèle de vue lorsque l'utilisateur   déplace le focus à un contrôle différent, ou dans le cas de   des éléments, immédiatement après tout changement

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

    •   
    • « keyPress » - met à jour votre modèle de vue lorsque l'utilisateur a tapé un   clé. Contrairement à keyup, cette mise à jour à plusieurs reprises pendant que l'utilisateur possède une clé   vers le bas

    •   
    • « afterkeydown » - met à jour votre modèle de vue dès que l'utilisateur   commence à taper un caractère. Cela fonctionne en attrapant les années du navigateur   événement keydown et gestion de l'événement de manière asynchrone.
    •   
  •   
     

Parmi ces options « afterkeydown » est le meilleur choix si vous voulez   Gardez votre modèle de vue mis à jour en temps réel.

Autres conseils

version 3.2 vous pouvez simplement utiliser textinput obligatoire. :

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

Il fait deux choses importantes:

  • des mises à jour immédiates
  • poignées différences de navigateur pour couper, glisser, autocomplete ...

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

Si vous voulez faire des mises à jour sur afterkeydown « par défaut », vous pouvez injecter le valueUpdate de liaison dans le gestionnaire de liaison value. Il suffit de fournir un nouveau allBindingsAccessor pour le gestionnaire à l'utilisation qui comprend 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 « remplaçant » l'value obligatoire, vous pouvez donner la coutume remplaçant la liaison d'un nom et une utilisation différente que la liaison gestionnaire.

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

demo

Une telle solution serait appropriée pour la version knock-out 2.x. L'équipe Knockout a étoffé une reliure plus complète pour le texte ressemblant à des entrées à travers le textInput obligatoire dans la version 3 et Knockout vers le haut. Il a été conçu pour gérer toutes les méthodes de saisie de texte pour les entrées de texte et textarea. Il va même gérer la mise à jour en temps réel ce qui rend effectivement cette approche obsolète.

La réponse de Jeff Mercado est fantastique, mais malheureusement rompu avec Knockout 3.

Mais j'ai trouvé la réponse suggérée par les ko devs en travaillant avec Knockout 3 changements. Voir https://github.com/knockout/knockout/pull/932. Leur 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/

Modifier Ko 3.2.0 a maintenant une solution plus complète avec le nouveau « textInput » obligatoire. Voir la réponse SalvidorDali

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top