[英]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中展開訪問者會創建一個觸發器,以便在訪問者值發生更改時重新評估綁定。 然后在第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.