मैं खोए हुए फ़ोकस के बजाय कीबोर्ड पर डेटा-बाइंड को नॉकआउट जेएस कैसे प्राप्त कर सकता हूं?


191

नॉकआउट js का यह उदाहरण तब काम करता है जब आप किसी फ़ील्ड को संपादित करते हैं और TAB, व्यूमॉडल डेटा को दबाते हैं और इसलिए फ़ील्ड के नीचे का टेक्स्ट अपडेट किया जाता है।

मैं इस कोड को कैसे बदल सकता हूं ताकि हर कुंजीपट पर व्यूमाडेल डेटा अपडेट हो जाए?

वैकल्पिक शब्द

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

9
KO 3.2 में इन सभी वर्कआर्ड को करने की आवश्यकता नहीं है: stackoverflow.com/a/25493265/1090562
साल्वाडोर डाली

साल्वाडोर सही है - यह नवीनतम संस्करण में स्वचालित रूप से करता है।
vapcguy

जवाबों:


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

से प्रलेखन

अतिरिक्त पैरामीटर

  • valueUpdate

    यदि आपके बाइंडिंग में valueUpdate नामक एक पैरामीटर भी शामिल है, तो यह परिभाषित करता है कि परिवर्तन का पता लगाने के लिए कौन से ब्राउज़र ईवेंट KO का उपयोग करना चाहिए। निम्न स्ट्रिंग मान सबसे उपयोगी विकल्प हैं:

    • "परिवर्तन" (डिफ़ॉल्ट) - उपयोगकर्ता द्वारा किसी भिन्न नियंत्रण पर, या तत्वों के मामले में, बिना किसी बदलाव के तुरंत बाद, अपने दृश्य मॉडल को अपडेट करता है

    • "कीअप" - उपयोगकर्ता द्वारा कुंजी जारी करने पर अपना दृश्य मॉडल अपडेट करता है

    • "कीपर" - जब उपयोगकर्ता ने एक कुंजी टाइप की है, तो अपना दृश्य मॉडल अपडेट करें। की-अप के विपरीत, यह अपडेट बार-बार होता है जबकि उपयोगकर्ता एक कुंजी दबाए रखता है

    • "afterkeydown" - जैसे ही उपयोगकर्ता एक चरित्र लिखना शुरू करता है, अपने दृश्य मॉडल को अपडेट करता है। यह ब्राउज़र की कीडाउन इवेंट को पकड़कर और एसिंक्रोनस रूप से ईवेंट को हैंडल करके काम करता है।

इन विकल्पों में से, "afterkeydown" सबसे अच्छा विकल्प है यदि आप अपने दृश्य मॉडल को वास्तविक समय में अपडेट रखना चाहते हैं।


9
डॉक्स से नॉकआउट में। js: // सिंटैक्स "के बाद <Eventname>" का अर्थ है "हैंडलर को एसिंक्रोनस रूप से चलाने के बाद ईवेंट" // यह उपयोगी है, उदाहरण के लिए, ब्राउज़र को कंट्रोल अपडेट करने के बाद "कीडड" इवेंट को पकड़ने के लिए।
जॉन राइट

4
वैल्यू पाने के लिए वैसे भी क्या है: डिफ़ॉल्ट होने के लिए 'afterkeydown' ?
एरोन शफोवालॉफ सेप

2
कुछ इनपुट बॉक्स के लिए ब्राउज़र "ऑटो-पॉप्युलेट" मान दिखाता है (जैसे कि इनपुट फ़ील्ड का नाम "फर्स्टनाम" है)। ऑटो-पॉपुलेट फ्लॉप से ​​"afterkeydown" के साथ काम करना। क्या इसे पकड़ने का कोई तरीका है?
एंटोन

2
@ एटन ऑटो-पॉप्युलेट वैल्यू के अलावा, ऑन-स्क्रीन कीबोर्ड क्लिक और माउस पेस्ट इवेंट भी हैं जिन्हें पकड़ा जाना चाहिए। उपयोग करना afterkeydownएक बुरा समाधान है।
जॉन कुर्लाक

2
इस उत्तर के लेखक, कृपया सल्वाडोर डाली के उत्तर को भी शामिल करें, 3.2 के रूप में textInput जोड़ा एक बेहतर उपाय है क्योंकि इसमें मोबाइल ब्राउज़रों के साथ बेहतर संगतता है (ऑटो पूर्ण कार्य की तरह बेहतर)
माइकल क्रुक

85

में संस्करण 3.2 आप बस का उपयोग कर सकते बाध्यकारी TextInput। :

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

यह दो महत्वपूर्ण काम करता है:

  • तत्काल अपडेट करें
  • कट, ड्रैग, स्वतः पूर्ण के लिए ब्राउज़र अंतर संभालता है ...

तो अतिरिक्त मॉड्यूल, कस्टम नियंत्रण और अन्य चीजों के लिए कोई ज़रूरत नहीं है।


यह वास्तव में अच्छी तरह से काम करता है और वास्तव में वही है जो मुझे मूल्य को बदलने के लिए आवश्यक है: फ़ील्ड, मान: अद्यतन: 'इनपुट परिवर्तन' जो कि मैंने अपने ऐप के माध्यम से किया था ... :) धन्यवाद।
टॉड थॉमसन

क्या घटना को पकड़ने का एक तरीका है जब कोई उपयोगकर्ता नए HTML5 खोज इनपुट फ़ील्ड पर 'x' आइकन पर क्लिक करता है और इनपुट खाली होने की स्थिति में कार्य करता है?
कोड्रिना वालो

35

यदि आप इसे afterkeydown"डिफ़ॉल्ट रूप से" अपडेट करना चाहते हैं , तो आप बाइंडिंग हैंडलर valueUpdateमें बाइंडिंग को इंजेक्ट कर सकते हैं value। बस allBindingsAccessorहैंडलर के लिए एक नया सप्लाई करें जिसमें शामिल हो 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
    };
} ());

यदि आप valueबाध्यकारी "ओवरराइडिंग" करने में सहज नहीं हैं , तो आप ओवरराइडिंग कस्टम को एक अलग नाम देने और उस बाइंडिंग हैंडलर का उपयोग कर सकते हैं।

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

डेमो

इस तरह का एक समाधान नॉकआउट संस्करण 2.x के लिए उपयुक्त होगा। नॉकआउट टीम ने नॉकआउट संस्करण 3 और पाठ में टेक्स्टइन्पुट बाइंडिंग के माध्यम से पाठ जैसे इनपुट के लिए एक और अधिक पूर्ण बाध्यकारी बनाया है । यह पाठ इनपुट के लिए सभी पाठ इनपुट विधियों को संभालने के लिए डिज़ाइन किया गया था और textarea। यह भी वास्तविक समय अद्यतन जो प्रभावी ढंग से इस दृष्टिकोण अप्रचलित प्रदान करता है संभाल लेंगे।


2
इस तरह मेरा मार्कअप थोड़ा टिडियर हो जाता है। इसके अलावा, 'afterkeydown' के अलावा, 'input' और 'paste' ईवेंट्स को पेस्ट / ड्रैग-एंड-ड्रॉप क्रियाओं को संभालने के लिए जोड़ा जा सकता है।
बॉब

उपरोक्त समाधान में मुझे लगता है कि "typeof valueUpdated === 'array'" को "object.prototype.toString.call (valueUpdate) === '[object Array]' के साथ बदलने की आवश्यकता है। देखें stackoverflow.com/questions/4775722/…
daveywc

20

जेफ मर्काडो का जवाब शानदार है, लेकिन दुर्भाग्य से नॉकआउट 3 से टूट गया।

लेकिन मुझे नॉकआउट 3 परिवर्तनों के माध्यम से काम करते हुए को देवों द्वारा सुझाए गए उत्तर का पता चला। नीचे की टिप्पणियाँ https://github.com/knockout/knockout/pull/932 पर देखें । उनका कोड:

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

संपादित करें को 3.2.0 अब नए "textInput" बाइंडिंग के साथ एक और अधिक पूर्ण समाधान है। देखें साल्विडोरडाली का जवाब


1
3.0 का जवाब अपडेट करने के लिए धन्यवाद!
ग्राहम टी

@ KO 3.2 में ग्राहम आपको इसकी आवश्यकता भी नहीं है। यह सिर्फ एक पंक्ति है
साल्वाडोर डाली

KO 3.2 पर हम में से उन लोगों के लिए बहुत अच्छा है जो TextInput के बारे में नहीं जानते थे जब हमने शुरुआत की थी, और पूरे सिस्टम में हर इनपुट को अपडेट नहीं कर सकते थे!
cscott530 15
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.