[英]show underlying value of input on focus knockout custom binding
我在淘汰賽中創建了以下綁定處理程序(請原諒,現在只是將它們一起砍掉!)
所需的功能是,如果一個字段為數字,則在顯示時將其格式設置為小數點后綴“ X”(默認為2),但輸入的基礎值將為小數。
一切正常,但是我想添加一個功能,當輸入成為焦點時,它會顯示實際值,我只是不知道該怎么做。
即
是第3點,我不知道該如何實現,因為它現在顯示1.11,然后在模糊時覆蓋?
誰能為我指出正確的方向-基本上我可以在哪里訪問基礎值並將焦點替換為基礎值?
為簡便起見,我刪除了一些其他的“裝飾”代碼,這些代碼包裝了輸入,因為它們並不相關。
提前致謝。
ko.bindingHandlers.specialInput = {
init: function (element, valueAccessor, allBindingsAccessor) {
var value = valueAccessor();
var decimals = allBindingsAccessor().decimals || 2;
var formatString = "";
var interceptor = ko.computed({
read: function () {
if(isNumeric(ko.unwrap(value))){
//to do if time - replace this with a function that will accept any number of decimals
if(decimals == 0){
formatString = "0,0";
}
if(decimals == 1){
formatString = "0,0.0";
}
if(decimals == 2){
formatString = "0,0.00";
}
if(decimals == 3){
formatString = "0,0.000";
}
if(decimals == 4){
formatString = "0,0.0000";
}
if(decimals == 5){
formatString = "0,0.00000";
}
return numeral(ko.unwrap(value)).format(formatString);
}else{
return ko.unwrap(value);
}
},
write: function (newValue) {
if ($.trim(newValue) == '')
value("");
else
if(isNumeric(newValue)){
value(numeral().unformat(newValue));
value.valueHasMutated();
}else{
value(newValue);
value.valueHasMutated();
}
}
}).extend({notify: 'always'});
if (element.tagName.toLowerCase() == 'input') {
ko.applyBindingsToNode(element, {
value: interceptor
});
} else {
ko.applyBindingsToNode(element, {
text: interceptor
});
}
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = ko.unwrap(valueAccessor());
return ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
}
};
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
我不會用計算出的interceptor
來實現這一點。
我寧願執行以下操作:
在init
注冊事件處理程序中,用於在init
進行focus
和blur
處理:
focus
處理程序上,您必須在輸入中顯示基礎值 blur
處理程序上,您必須將數字存儲在文本框中,並在輸入中顯示四舍五入的值 在update
您必須存儲實際值,並將其顯示在文本框中。 更新值時,文本框很可能沒有焦點,因此應該放心顯示四舍五入的值。 但是,如果您認為在某些情況下可以將其聚焦,則可以執行以下操作來測試它以確定如何顯示該值: 使用jQuery測試輸入是否具有焦點
ko.bindingHandlers.yourBindingName = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var $element = $(element);
$element.on('focus', function() {
// Show raw value:
$element.val(/* raw value */);
});
$element.on('blur', function() {
// Update the observable with the value in the input
ko.unwrap(valueAccessor())( /* get raw value from input */);
// Show the rounded value
$element.val(/* rounded value */);
});
// Update will be called after init when the binding is first applied,
// so you don't have to worry about what it's initially shown
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// When the value changes, show it in the input
$.element.val(/* if focused show raw, if not, show roundede*/);
}
};
如果您確定只將其與input
和可寫可觀察對象一起使用,則此代碼是安全的。 如果對此有疑問,則應添加許多檢查,例如檢查使用jQuery .val()
或.text()
的元素的種類,檢查綁定表達式是否可寫,以觀察其值,等等。
注意:有很多事情需要監督:銷毀元素時我們不再需要的對象(例如,如果使用'if','whit'或'template',則可能發生)。 在這種情況下,我認為您不需要這樣做,但是請查看以下內容: 自定義處理邏輯(如果您認為需要銷毀某些東西)。
在綁定處理程序中使用jQuery並沒有錯,但是您也可以使用現有的綁定處理程序非常簡單地完成此操作。 可以將其整合到組件中以進行重用(盡管在我的示例中我沒有這樣做)。
您只需要一個值的后備存儲,然后計算的結果就會返回后備存儲或格式化的后備存儲,具體取決於輸入是否具有焦點(使用hasFocus
綁定)。
vm = (function() { var editing = ko.observable(false), backingStore = 0, value = ko.computed({ read: function() { return editing() ? backingStore : (+backingStore).toFixed(2); }, write: function(newValue) { backingStore = newValue; } }); return { editing: editing, value: value } }()); ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <input data-bind="hasFocus: editing, value: value" /> <input />
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.