KnockoutJS绑定与输入掩码混乱 [英] KnockoutJS binding messes with input mask

查看:102
本文介绍了KnockoutJS绑定与输入掩码混乱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将输入掩码应用于电话领域.在我应用KnockoutJS绑定之前,它一直有效,该绑定将删除蒙版,直到该字段获得焦点为止.

不起作用: http://jsfiddle.net/8r6fe/

$('[data-mask]').each(function () {
    console.log('mask');
    $this = $(this);
    var mask = $this.attr('data-mask') || 'error...', mask_placeholder = $this.attr('data-mask-placeholder') || 'X';

    $this.mask(mask, {
        placeholder: mask_placeholder
    });
})


var ViewModel = function() {
    this.firstName = ko.observable("");
    this.lastName = ko.observable("");
    this.phone = ko.observable("");

    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);

    this.firstName('John');
    this.lastName('Doe');
    this.phone('1231231234');
}; 
ko.applyBindings(new ViewModel());

作品: http://jsfiddle.net/gxhjn/

var ViewModel = function(first, last) {
    this.firstName = ko.observable(first);
    this.lastName = ko.observable(last);

    this.fullName = ko.computed(function() {
        // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName.
        return this.firstName() + " " + this.lastName();
    }, this);
};

ko.applyBindings(new ViewModel("Planet", "Earth")); // This makes Knockout get to work

$('[data-mask]').each(function () {
    console.log('mask');
    $this = $(this);
    var mask = $this.attr('data-mask') || 'error...', mask_placeholder = $this.attr('data-mask-placeholder') || 'X';

    $this.mask(mask, {
        placeholder: mask_placeholder
    });
})

解决方案

我不认为这是一个淘汰赛问题,但与屏蔽输入插件的设计方式有关的问题:您的初始值必须与屏蔽条件匹配.即使您摆脱淘汰赛,仅使用jQuery的val()函数将值设置为"1231231234",您也会看到相同的行为.

更新

抱歉,错过了您的作品"链接.我首先会建议一个自定义绑定处理程序.看起来这是要走的路.它会在通过敲除来更新文本后,在文本后加上 遮罩,然后使用新的遮罩值(如果需要的话)来更新视图模型:

ko.bindingHandlers.maskedInput = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.bindingHandlers.value.init(element, valueAccessor, allBindings, viewModel, bindingContext);
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.bindingHandlers.value.update(element, valueAccessor, allBindings, viewModel, bindingContext);
        $(element).mask(allBindings.get('mask'));
        valueAccessor()($(element).val());
    }
};

这是您更新的小提琴: http://jsfiddle.net/8r6fe/3/

I'm trying to apply an input mask to a telephone field. It works until I apply KnockoutJS binding, which removes the mask until the field receives focus.

Does not work: http://jsfiddle.net/8r6fe/

$('[data-mask]').each(function () {
    console.log('mask');
    $this = $(this);
    var mask = $this.attr('data-mask') || 'error...', mask_placeholder = $this.attr('data-mask-placeholder') || 'X';

    $this.mask(mask, {
        placeholder: mask_placeholder
    });
})


var ViewModel = function() {
    this.firstName = ko.observable("");
    this.lastName = ko.observable("");
    this.phone = ko.observable("");

    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);

    this.firstName('John');
    this.lastName('Doe');
    this.phone('1231231234');
}; 
ko.applyBindings(new ViewModel());

Works: http://jsfiddle.net/gxhjn/

var ViewModel = function(first, last) {
    this.firstName = ko.observable(first);
    this.lastName = ko.observable(last);

    this.fullName = ko.computed(function() {
        // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName.
        return this.firstName() + " " + this.lastName();
    }, this);
};

ko.applyBindings(new ViewModel("Planet", "Earth")); // This makes Knockout get to work

$('[data-mask]').each(function () {
    console.log('mask');
    $this = $(this);
    var mask = $this.attr('data-mask') || 'error...', mask_placeholder = $this.attr('data-mask-placeholder') || 'X';

    $this.mask(mask, {
        placeholder: mask_placeholder
    });
})

解决方案

I don't think this is a knockout issue, but an issue with the way the masked input plugin is designed: Your initial value must match the mask criteria. Even if you get rid of knockout and just use jQuery's val() function to set the value to "1231231234", you'll see the same behavior.

UPDATE

Sorry, missed your "works" link. I was going to suggest a custom binding handler in the first place. Looks like this is the way to go. It applies the masking after the text has been updated by knockout, and then updates the view model with the new, masked value (if that's what you want):

ko.bindingHandlers.maskedInput = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.bindingHandlers.value.init(element, valueAccessor, allBindings, viewModel, bindingContext);
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.bindingHandlers.value.update(element, valueAccessor, allBindings, viewModel, bindingContext);
        $(element).mask(allBindings.get('mask'));
        valueAccessor()($(element).val());
    }
};

Here's your updated fiddle: http://jsfiddle.net/8r6fe/3/

这篇关于KnockoutJS绑定与输入掩码混乱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆