【问题标题】:Custom Knockout binding not working correctly自定义淘汰赛绑定无法正常工作
【发布时间】:2017-06-18 11:39:15
【问题描述】:

我创建了一个计算出的 observable,它可以很好地格式化电话号码。当焦点离开表单域时,它将获取一串数字并将其剥离为 xxx-xxx-xxxx 格式。然后我有一个控制器操作将其剥离为 xxxxxxxxxx 格式,然后再保存到数据库中。然后我计算出的 observable 将其重新格式化为 xxx-xxx-xxxx 格式。

我现在想要创建一个可重用的自定义绑定处理程序,该处理程序可以在我们的应用程序中实现。问题是我无法让它完成最后一部分,它在表单字段中重新格式化它。所以,问题是当我单击更新时,表单字段将数字显示为 xxxxxxxxxx(与数据库中的方式相同)有谁知道我需要通过自定义绑定工作来更改什么,就像我当前计算的 observable 一样?

可观察:

self.Phone = ko.observable(model.MainPhone ? model.MainPhone : "").extend({ maxLength: 20, minLength: 10 });

Computed Observable 工作正常:

self.PhoneFormat = ko.computed(function () {
   var phoneFormatting = self.Phone()
       .replace(/\D+/g, "")
       .replace(/^[01]/, "")
       .replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3")
       .substring(0, 12);
   return self.Phone() ? self.Phone(phoneFormatting) : "";
}, self);

自定义绑定无法正常工作:

ko.bindingHandlers.formatPhone = {
    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);
    },

    update: 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.update(element, formatter, allBindings);
    }
};

【问题讨论】:

  • 你能显示与“当我点击更新”相关的代码吗?那是一个按钮吗?更新究竟做了什么?
  • 当然杰森!它是一个按钮,控制器代码如下:client.ContactPhone = phoneNumber == null ? null : Regex.Replace(phoneNumber, @"[^\d]", "");
  • 哦,它用于更新客户信息页面上字段的任何更改。
  • 取出你的update函数并将value.init调用替换为ko.applyBindingAccessorsToNode(element, { value: formatter }, bindingContext)(你还需要扩展你的init以获得bindingContext)。

标签: javascript mvvm knockout.js


【解决方案1】:

感觉readwrite 应该互换一下……

我想说您希望您的“源”数据只是数字。格式化后的数据主要用于展示。

我希望在您的绑定中添加一个computed 层,它可以做两件事:

  • 写的时候先去掉格式再放到source
  • 阅读时,以正确的格式添加

我不确定我是否破坏了您之前使用的东西,但可能是这样的:

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

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

var vm = { phoneNr: ko.observable("3456546512") };

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
Via custom binding:
<input data-bind="formatPhone: phoneNr">
<br/>
Mimic external update:
<input data-bind="textInput: phoneNr">

【讨论】:

  • 谢谢杰森。它就像一个魅力!您是否已经使用 Knockout 很长时间了?
  • 实际上我被困在一个会议中,而 user3297291 打败了我。也许他的名字也叫杰森;)
  • 哈!刚刚意识到不是你... :) 感谢用户!
  • @user3297291 似乎还是有问题。当我最初将焦点从现场移开时,格式化工作。但是,如果我第二次返回它,添加一些前导空格和一些特殊字符,它不会重新评估该值并重新格式化它。 :( 有什么想法吗?
  • @JasonSake 似乎还是有问题。当我最初将焦点从该字段移开时,格式会起作用。但是,如果我第二次返回它,添加一些前导空格和一些特殊字符,它不会重新评估该值并重新格式化它。 :( 有什么想法吗?
【解决方案2】:

我不确定为什么会这样,但自定义绑定没有。 :(

HTML:

<input data-bind="value: Phone" />

KO Observable:

self.Phone = ko.observable(model.Phone ? model.Phone : "").trimmed();

KO 可订阅:

ko.subscribable.fn.trimmed = function () {
        return ko.computed({
            read: function () {
                return this().replace(/\D+/g, "")
                               .replace(/^[01]/, "")
                               .replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3")
                               .substring(0, 12);
            },
            write: function (value) {
                this(value.replace(/\D+/g, "")
                               .replace(/^[01]/, "")
                               .replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3")
                               .substring(0, 12));
                this.valueHasMutated();
            },
            owner: this
        }).extend({ notify: 'always' });
    };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    相关资源
    最近更新 更多