2013-04-16 24 views
0

好日子淘汰賽:結合2個自定義綁定的數字 - 財務數據

我發現下面的兩個小提琴那不正是我想要什麼:

first Fiddle給我十進制格式。

second Fiddle給了我數字的數字分組。

我的問題:如何結合兩者爲一體,這樣我可以只使用它像這樣:

<b data-bind="commaDecimalFormatter: myNumber">This will output both demical notation and digital grouping</b> 

=============== ================================================== ================================================== =================================================

小提琴1級的代碼:

// Formatting Functions 
function formatWithComma(x, precision, seperator) { 
    var options = { 
     precision: precision || 2, 
     seperator: seperator || '.' 
    } 
    var formatted = parseFloat(x,10).toFixed(options.precision); 
    var regex = new RegExp(
      '^(\\d+)[^\\d](\\d{' + options.precision + '})$'); 
    formatted = formatted.replace(
     regex, '$1' + options.seperator + '$2'); 
    return formatted; 
} 

function reverseFormat(x, precision, seperator) { 
    var options = { 
     precision: precision || 2, 
     seperator: seperator || ',' 
    } 
    var regex = new RegExp(
     '^(\\d+)[^\\d](\\d+)$'); 
    var formatted = x.replace(regex, '$1.$2'); 
    return parseFloat(formatted); 
} 
// END: Formatting Functions 


// Custom Binding - place this in a seperate .js file and reference it in your html 
ko.bindingHandlers.commaDecimalFormatter = { 
    init: function(element, valueAccessor) { 

     var observable = valueAccessor(); 

     var interceptor = ko.computed({ 
      read: function() { 
       return formatWithComma(observable()); 
      }, 
      write: function(newValue) { 
       observable(reverseFormat(newValue)); 
      } 
     }); 

     if(element.tagName == 'INPUT') 
      ko.applyBindingsToNode(element , { 
       value: interceptor 
      }); 
     else 
      ko.applyBindingsToNode(element , { 
       text: interceptor 
      }); 
    } 
} 

// this is your viewmodel 
var vm = { 
    myNumber: ko.observable(100000) 
} 

// when the DOM is ready, call ko.applyBindings with your viewmodel 
$(function() { 
    ko.applyBindings(vm); 
}); 

FIDDLE 2代碼:

(function(){ 
    var format = function(value) { 
     toks = value.toFixed(2).replace('-', '').split('.'); 
     var display = '$' + $.map(toks[0].split('').reverse(), function(elm, i) { 
      return [(i % 3 === 0 && i > 0 ? ',' : ''), elm]; 
     }).reverse().join('') + '.' + toks[1]; 

     return value < 0 ? '-' + display : display; 
    }; 

ko.subscribable.fn.money = function() { 
    var target = this; 

    var writeTarget = function(value) { 
     var stripped=value 
      .replace(/[^0-9.-]/g, ''); 

     target(parseFloat(stripped)); 
    }; 

    var result = ko.computed({ 
     read: function() { 
      return target(); 
     }, 
     write: writeTarget 
    }); 

    result.formatted = ko.computed({ 
     read: function() { 
      return format(target()); 
     }, 
     write: writeTarget 
    }); 

    result.isNegative = ko.computed(function(){ 
     return target()<0; 
    }); 

    return result; 
}; 
})(); 

//Wire it up 
$(function() { 
    var viewModel = { 
     Cash: ko.observable(1000000).money(), 
    }; 


    viewModel.Total = ko.computed(function() { 
     return this.Cash(); 
    }, viewModel).money(); 
    ko.applyBindings(viewModel); 
}); 

回答

1

我不能組合這兩個函數。請嘗試以下,因爲你想要做什麼:十進制符號和數字分組:

JS:

function formatPrice(price) { 
     return price.reverse().replace(/((?:\d{2})\d)/g, '$1 ').reverse(); 
    } 

    // Need to extend String prototype for convinience 
    String.prototype.reverse = function() { 
     return this.split('').reverse().join(''); 
    } 

    $('.myNumber').each(function(){ 
     $(this).html(formatPrice($(this).html())); 
    }); 

Fiddle

注意:您需要刷新瀏覽器每次對jQuery來將輸出值(只讀)格式化爲數字分組......當然,當您在編輯器屏幕(第一個字段)中輸入新值並且沒有看到更新的數字分組時

+0

謝謝。不是最佳的,但這是做我想做的 –

0

我想提供替代解決方案。您也可以創建一個自定義綁定處理程序,它可以執行您想要的任何操作(這會使用您最初提出的語法)。

ko.bindingHandlers. commaDecimalFormatter = { 
    update: function(element, valueAccessor, allValuesAccessor) { 

    // This gets the current value of the observable from your model 
    var value = ko.utils.unwrapObservable(valueAccessor()); 

    // Manipulate `value` as desired using the bodies of the functions you mentioned 
    // Note: You don't want to use a global function, so actually take the bodies 
    // and put it here. Plain old JS :) 
    ... 

    // Set the value on the element 
    jQuery(element).text(value); 
    } 
};