Come posso ottenere Knockout JS ai dati-bind sulla pressione dei tasti, invece di perso-focus?

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

  •  10-10-2019
  •  | 
  •  

Domanda

Questo esempio di knockout js funziona così quando si modifica un campo e premere TAB, i dati ViewModel e, quindi, il testo sotto i campi viene aggiornato.

Come faccio a modificare il codice in modo che i dati ViewModel viene aggiornato ogni pressione di un tasto?

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>
È stato utile?

Soluzione

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

documentazione

  

Ulteriori parametri

     
      
  • valueUpdate

         

    Se il legame comprende anche un parametro chiamato valueUpdate, questo   definisce quale browser evento KO dovrebbe usare per rilevare i cambiamenti. Il   seguenti valori stringa sono le scelte più comuni utili:

         
        
    • "cambiamento" (impostazione predefinita) - aggiorna il modello di visualizzazione quando l'utente   sposta l'attivo a un controllo diverso, o in caso di   elementi, subito dopo ogni modifica

    •   
    • "KeyUp" - aggiorna il modello di visualizzazione quando l'utente rilascia un tasto

    •   
    • "pressione di un tasto" - aggiorna il modello di visualizzazione quando l'utente ha digitato un   chiave. A differenza di keyup, verrà aggiornato più volte mentre l'utente tiene un tasto   giù

    •   
    • "afterkeydown" - aggiorna il modello di vista non appena l'utente   inizia a digitare un carattere. Questo funziona catturando del browser   evento KeyDown e la gestione dell'evento in modo asincrono.
    •   
  •   
     

Di queste opzioni, "afterkeydown" è la scelta migliore se si vuole   mantenere il vostro modello di visualizzazione aggiornata in tempo reale.

Altri suggerimenti

Nel versione 3.2 si può semplicemente utilizzare textinput vincolante. :

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

Si fa due cose importanti:

  • effettuare aggiornamenti immediati
  • differenze maniglie del browser per il taglio, la resistenza, completamento automatico ...

senza necessità di moduli aggiuntivi, controlli personalizzati e altre cose.

Se si vuole fare gli aggiornamenti su afterkeydown "per difetto", è possibile iniettare il legame nel gestore di legame valueUpdate value. Basta fornire un nuovo allBindingsAccessor per il gestore di utilizzo che include 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
    };
} ());

Se non stai bene "override" legare il value, si potrebbe dare l'associazione di un nome e diverso uso personalizzato ignorando che il legame gestore.

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

demo

Una soluzione del genere sarebbe adatto per Knockout versione 2.x. Il team di Knockout ha concretizzati una più completa vincolante per gli ingressi attraverso il textInput vincolante Knockout versione 3 e il testo simile su. E 'stato progettato per gestire tutti i metodi di immissione del testo per l'input di testo e textarea. Sarà anche di gestire l'aggiornamento in tempo reale che rende efficace questo approccio obsoleto.

La risposta di Jeff Mercado è fantastica, ma purtroppo rotto con Knockout 3.

Ma ho trovato la risposta suggerita dalle sviluppatori ko mentre si lavora attraverso Knockout 3 cambi. Vedere i commenti di fondo a https://github.com/knockout/knockout/pull/932. Il loro codice:

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

Modifica Ko 3.2.0 ora ha una soluzione più completa con il nuovo "textInput" vincolante. Vedi la risposta di SalvidorDali

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top