2012-05-02 13 views
5

मैं एक कस्टम स्वत: पूर्ण को संभालने के लिए बाध्यकारी है थ्रोटल करते हैं, और मैं सर्वर से बात करते हैं और संक्षिप्त नाम के साथ text_field की जगह जब कोई उपयोगकर्ता स्वत: पूर्ण से किसी आइटम का चयन करता है। समस्या यह है कि यह दूसरी बार मेरे कस्टम बाध्यकारी के 'अद्यतन' समारोह को ट्रिगर करता है।Knockout.js - कैसे मैं कस्टम बाइंडिंग

Knockout.js कोड (संपादित करें: नोट पीछा कर रहा है CoffeeScript):

ko.bindingHandlers.ko_autocomplete = 
    init: (element, params) -> 
    $(element).autocomplete(params()) 

    update: (element, valueAccessor, allBindingsAccessor, viewModel) -> 
    unless task.name() == undefined 
     $.ajax "/tasks/name", 
     data: "name=" + task.name(), 
     success: (data,textStatus, jqXHR) -> 
      task.name(data.short_name) 


    Task = -> 
    @name = ko.observable() 
    @name_select = (event, ui) -> 
     task.name(ui.item.name) 
     false 

    task = Task.new() 

देखें

= f.text_field :name, "data-bind" => "value: name, ko_autocomplete: { source: '/autocomplete/tasks', select: name_select }" 

वहाँ एक कस्टम बाइंडिंग के लिए एक थ्रोटल लागू करने के लिए कोई तरीका है?

मैं सिर्फ कस्टम बाइंडिंग 'अपडेट' समारोह को दूसरी बार जब मैं सर्वर से वापस भेज दिया short_name को task.name सेट पर आरंभ होने से रोकना चाहते हैं।

उत्तर

3

सामान्य तौर पर, मैं इस तरह एक पैटर्न

ko.bindingHandlers.gsExample = 
    update: (element, valueAccessor, allBindingsAccessor, viewModel) -> 
     args = valueAccessor() 

     # Process args here, turn them into local variables 
     # eg. 
     span = args['span'] || 10 

     render = ko.computed -> 
      # Put your code in here that you want to throttle 
      # Get variables from things that change very rapidly here 

      # Note: You can access variables such as span in here (yay: Closures) 
      some_changing_value = some_observable() 

      $(element).html(some_changing_value) 

     # Now, throttle the computed section (I used 0.5 seconds here) 
     render.extend throttle : 500 

     # Cause an immediate execution of that section, also establish a dependancy so 
     # this outer code is re-executed when render is computed. 
     render() 
+2

यह महत्वपूर्ण है कि आप नए गणना बाध्यकारी ठीक से निपटारा करने के लिए अनुमति देने के लिए disposeWhenNodeIsRemoved विकल्प जोड़ने है हो जाएगा, अन्यथा आप मेमोरी लीक और अपमानजनक प्रदर्शन या बुरा है। –

2

आप अलगाव का उल्लंघन करने के, तो आप स्वत: पूर्ण की देरी विकल्पों का उपयोग कर सकते हैं नहीं करना चाहती है और यह घटना का चयन है, अद्यतन समारोह फेंक दूर हैं।

इस तरह से अपने init संशोधित करें: क्योंकि (सरलीकरण के लिए) अद्यतन ही गणना की किसी तरह का है

var options = $.extend(params(), { 
     select: function(ev, ui) { 
     var name = ui.item ? ui.item.short_name : this.value 
     task.name(name); 
     } 
    }) 
    $(element).autocomplete(options) 

आपका अद्यतन दूसरी बार कहा जाता है। तो यह इसके अंदर पहुंचने योग्य हर अवलोकन की सदस्यता लेता है। इस लाइन में unless task.name() == undefined आप task.name() पर अपडेट की सदस्यता लेते हैं। फिर जब आप AJAX अनुरोध की सफलता पर task.name(data.short_name) के साथ अपना अवलोकन योग्य अपडेट करते हैं, तो अपडेट अधिसूचित और पुनः संयोजित हो जाते हैं।

+0

btw मेरे लिए काम करने के लिए मिल गया है, क्या tran.dr_name() है? – ILya

+0

tran.dr_name() एक टाइपो था, task.name() में बदल गया। – map7

+0

तो मैं एक explaination जोड़ने क्यों अपने अद्यतन दूसरी बार – ILya

संबंधित मुद्दे