簡體   English   中英

自定義Knockout綁定無法正常工作

[英]Custom Knockout binding not working

我目前正在使用事件綁定來格式化電話號碼(到xxx-xxx-xxxx格式),我想創建一個可重復使用的自定義綁定,以便將來在我們的應用程序中使用。 當前事件綁定工作正常,但我無法使自定義綁定正常工作。 任何人都可以看看下面,告訴我我的問題?

使用viewModel方法綁定當前事件:

<input class="form-control" id="Phone"  type="text" 
       data-bind="event: {blur: formatPhone}, enable: isInputMode, value: Phone" />

self.Phone = ko.observable(model.MainPhone).extend({ maxLength: 20 });

self.formatMainPhone = function() {
        var tempString = self.Phone().replace(/\D+/g, "").replace(/^[01]/, "").replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3").substring(0, 12);
        self.Phone(tempString);
    }

自定義綁定處理程序不起作用:

<input class="form-control max225" id="Phone" type="text" 
           data-bind="formatPhoneNumber: Phone, enable: isInputMode, value: Phone" />

self.Phone = ko.observable(model.MainPhone).extend({ maxLength: 20 });

ko.bindingHandlers.formatPhoneNumber = {
        update: function (element, valueAccessor) {            
            var phone = ko.utils.unwrapObservable(valueAccessor());
            var formatPhone = function () {
                return phone.replace(/\D+/g, "").replace(/^[01]/, "").replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3").substring(0, 11);
            }
            ko.bindingHandlers.value.update(element, formatPhone);
        }
    };

您的綁定試圖劫持默認“值”綁定的更新,該綁定查看了淘汰源代碼,似乎已被棄用。

'update': function() {} // Keep for backwards compatibility with code that may have wrapped value binding

您必須更改綁定,以便它使用init。

ko.bindingHandlers.value.init(element, formatPhone, allBindings);

編輯:

這可能更接近你想要的。 而不是使用更新綁定,這將創建一個中間計算observable,然后使用value.init將文本框綁定到該。 我們永遠不需要更新綁定,因為計算將負責為您傳播更改。

ko.bindingHandlers.formatPhoneNumber = {
    init: function (element, valueAccessor, allBindings) {            
      var source = valueAccessor();      
      var formatter = function(){
        return ko.computed({
          read: function(){ return source(); },
          write: function(newValue){
            source(newValue.replace(/\D+/g, "").replace(/^[01]/, "").replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3").substring(0, 12));
          }
        })
      };

      ko.bindingHandlers.value.init(element, formatter, allBindings);
    }
  };

編輯2 - 更多解釋

使用formatPhoneNumber的更新綁定告訴knockout在值發生變化時運行該代碼。 這在理論上聽起來不錯,但讓我們把它分解。

  1. 打開訪問器並獲得平坦值。
  2. 創建一個返回格式化值的格式函數。
  3. 搭載使用格式函數的值綁定。

因為這是一個更新綁定,所以在步驟1中展開訪問者會創建一個觸發器,以便在訪問者值發生更改時重新評估綁定。 然后在第3步中,你告訴knockout重新執行value.update綁定,它當前只是一個空函數,什么都不做。 如果你改變它來使用value.init而事實上可能實際上用於格式化輸出,但是你告訴knockout每次值改變時重新初始化init綁定。

update: function(element, valueAccessor, allBindings) {
    var phone = ko.utils.unwrapObservable(valueAccessor());
    var formatPhone = function() { return phone.replace(...)}
    ko.bindingHandlers.value.init(element, formatPhone, allBindings);
}

重新創建綁定並傳遞新的初始值。 這也意味着它只是一個單向綁定,因為對前端的更改不能使其返回到模型以更新后備可觀察對象。

現在,如果您將自己的綁定更改為init綁定,並從那里調用value.init綁定,它只會初始化一次,但下一個問題是您綁定的函數不會知道什么時候更新。

init: function(element, valueAccessor, allBindings) {
    var phone = ko.utils.unwrapObservable(valueAccessor());
    var formatPhone = function() { return phone.replace(...)}
    ko.bindingHandlers.value.init(element, formatPhone, allBindings);
}

因為它只是一個正常的js函數,它正在傳遞一個已經解開的平坦值,它總是會根據手機的原始值給出相同的結果。 傳遞value.init綁定計算的observable,確保對accessor observable的更新觸發format函數從現有綁定中更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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