2012-12-21 16 views
9

मेरे पास व्यू-मॉडल में 3 अवलोकन योग्य चर हैं, और स्वरूपित मान को आउटपुट करना चाहते हैं। हालांकि, मैं उनमें से प्रत्येक के लिए गणना विधि नहीं लिखना चाहता क्योंकि वे समान हैं। कोड का पुन: उपयोग करने का सबसे अच्छा तरीका क्या है? धन्यवाद।चर के एक समूह के लिए स्वरूपित मानों के लिए एक गणना किए गए अवलोकन योग्य बनाएं

कोड मैं प्राप्त करने के लिए जा रहा हूँ है:

this.formattedPrice = ko.computed({ 
     read: function() { 
      return '$' + this.price().toFixed(2); 
     }, 
     write: function (value) { 
      // Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable 
      value = parseFloat(value.replace(/[^\.\d]/g, "")); 
      this.price(isNaN(value) ? 0 : value); // Write to underlying storage 
     }, 
     owner: this 
    }); 

और विफल रहा है उदाहरण में है: Jsfiddle

धन्यवाद,

उत्तर

17

यहां कुछ तरीके हैं जिनसे आप यह पुन: प्रयोज्य बना सकते हैं।

यदि आप इसे अपने दृश्य मॉडल में संभालना चाहते हैं, तो एक अच्छा विकल्प एक एक्सटेंशन बनाना है जो प्रारूपित गणना किए गए अवलोकन योग्य को आपके मूल के "सब-अवलोकन योग्य" के रूप में संग्रहीत करेगा। आप extenders का उपयोग करके या fn ऑब्जेक्ट को here वर्णित अनुसार जोड़कर अवलोकन कर सकते हैं। मैं बाद वाले को पसंद करता हूँ।

तो, आप withCurrencyFormat नामक अवलोकनों में एक फ़ंक्शन जोड़ सकते हैं। यह ऐसा दिखाई देगा:

ko.observable.fn.withCurrencyFormat = function(precision) { 
    var observable = this; 
    observable.formatted = ko.computed({ 
     read: function (key) { 
      return '$' + (+observable()).toFixed(precision); 
     }, 
     write: function (value) { 
      value = parseFloat(value.replace(/[^\.\d]/g, "")); 
      observable(isNaN(value) ? null : value); // Write to underlying storage 
     }   
    }); 

    return observable; 
}; 

अब, आप कह सकते हैं:

self.week1Amount = ko.observable(w1).withCurrencyFormat(2); 
self.week2Amount = ko.observable(w2).withCurrencyFormat(2); 
self.week3Amount = ko.observable(w3).withCurrencyFormat(2); 

और इसके खिलाफ बाँध की तरह यूआई में:

<td><input data-bind="value: week1Amount.formatted" /></td> 
    <td><input data-bind="value: week2Amount.formatted" /></td> 
    <td><input data-bind="value: week3Amount.formatted" /></td> 

नमूना यहाँ: http://jsfiddle.net/rniemeyer/xskJN/

एक और पसंद इसे बाध्यकारी में ले जाना है, ताकि आप अकेले अपना दृश्य मॉडल छोड़ सकें। यह समान कोड का प्रयोग करेंगे, लेकिन एक कस्टम बाध्यकारी हैंडलर में है कि ऐसा दिखाई देगा:

ko.bindingHandlers.valueAsCurrency = { 
    init: function(element, valueAccessor) { 
     var observable = valueAccessor(), 
      formatted = ko.computed({ 
       read: function (key) { 
        return '$' + (+observable()).toFixed(2); 
       }, 
       write: function (value) { 
        value = parseFloat(value.replace(/[^\.\d]/g, "")); 
        observable(isNaN(value) ? null : value); // Write to underlying storage 
       }, 
       disposeWhenNodeIsRemoved: element     
      }); 

     //apply the actual value binding with our new computed 
     ko.applyBindingsToNode(element, { value: formatted }); 
    }   
}; 

तो बाध्यकारी हैंडलर हम बना रहे हैं में, हमारी गणना और फिर इसके खिलाफ बाध्यकारी value का उपयोग कर।

अब, अपने दृश्य मॉडल में कोई बदलाव नहीं की आवश्यकता होगी और आप जैसे यूआई में बाँध होगा:

<td><input data-bind="valueAsCurrency: week1Amount" /></td> 
    <td><input data-bind="valueAsCurrency: week2Amount" /></td> 
    <td><input data-bind="valueAsCurrency: week3Amount" /></td> 

नमूना यहाँ: http://jsfiddle.net/rniemeyer/sD6y4/

+0

धन्यवाद, आरपी। यह पूरी तरह से काम करता है। –

+0

मेरे पास एक और सवाल है, इसे योग क्षेत्र में कैसे लागू करें, जो केवल पढ़ने के लिए है। फिर, मेरा कामकाजी कोड http://jsfiddle.net/sD6y4/4/ है। चूंकि मेरे पास sum1, sum2, ..., फ़ील्ड हैं। क्या इस मामले में पुन: प्रयोज्य कार्य करना संभव है? अग्रिम में धन्यवाद! –

+0

आप 'textAsCurrency' बाध्यकारी जोड़ सकते हैं जो केवल' read' भाग करता है और 'text' बाध्यकारी लागू करता है। ऐसा लगता है: http://jsfiddle.net/rniemeyer/3nrKD/ –