簡體   English   中英

在焦點敲除自定義綁定上顯示輸入的基礎值

[英]show underlying value of input on focus knockout custom binding

我在淘汰賽中創建了以下綁定處理程序(請原諒,現在只是將它們一起砍掉!)

所需的功能是,如果一個字段為數字,則在顯示時將其格式設置為小數點后綴“ X”(默認為2),但輸入的基礎值將為小數。

一切正常,但是我想添加一個功能,當輸入成為焦點時,它會顯示實際值,我只是不知道該怎么做。

  1. 用戶在輸入中輸入1.1121
  2. 當他們離開輸入時,其格式為1.11
  3. 如果他們返回輸入(焦點),則會顯示1.1121進行編輯

是第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進行focusblur處理:

  • 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM