【问题标题】:Knockout.js: time input format and value restrictionKnockout.js:时间输入格式和值限制
【发布时间】:2011-11-15 19:02:12
【问题描述】:

当我使用敲除在我的视图模型中绑定数字数据时,它会正确显示,但如果用户更改输入标记值,则会将数据类型更改为字符串。提交字符串的问题是服务器需要一个没有隐式转换的数值。

有什么方法可以告诉knockout保持原始属性值的数据类型?

我的示例代码将视图模型名称与输入标签名称相匹配。我使用不显眼的敲除来进行绑定,效果很好。

// Bind the first object returned to the first view model object
// FNS is the namespace, VM is the view model
FNS.VM.Items[0] = ko.mapping.fromJS(data.Items[0]);

// For each property found, find the matching input and bind it
$.each(FNS.VM.Items[0], function (indexInArray, valueOfElement) {
    var attrName = indexInArray;
    var attrValue;
    if (typeof valueOfElement == "function")
        attrValue = valueOfElement();
    else
        attrValue = valueOfElement;

    var a = $('input[name="' + attrName + '"][type="checkbox"]');
    if (a.length)
        a.dataBind({ checked: 'VM.Items[0].' + attrName });

    var b = $('input[name="' + attrName + '"][type="radio"]');
    if (b.length)
        b.dataBind({ checked: 'VM.Items[0].' + attrName });

    var c = $('input[name="' + attrName + '"][type="text"]');
    if (c.length)
        c.dataBind({ value: 'VM.Items[0].' + attrName });
});
ko.applyBindings(FNS);

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    这是一个线程,它使用几种不同的技术来保持数值:https://groups.google.com/d/topic/knockoutjs/SPrzcgddoY4/discussion

    一个选择是将这个问题推到你的视图模型中,并创建一个numericObservable 来使用而不是普通的 observable。它可能看起来像:

    ko.numericObservable = function(initialValue) {
        var _actual = ko.observable(initialValue);
    
        var result = ko.dependentObservable({
            read: function() {
                return _actual();
            },
            write: function(newValue) {
                var parsedValue = parseFloat(newValue);
                _actual(isNaN(parsedValue) ? newValue : parsedValue);
            }
        });
    
        return result;
    };
    

    示例:http://jsfiddle.net/rniemeyer/RJbdS/

    另一种选择是使用自定义绑定来处理此问题。您可以定义 numericValue 绑定并改用它,而不是使用 value 绑定。它可能看起来像:

    ko.bindingHandlers.numericValue = {
        init : function(element, valueAccessor, allBindings, data, context) {
            var interceptor = ko.computed({
                read: function() {
                    return ko.unwrap(valueAccessor());
                },
                write: function(value) {
                    if (!isNaN(value)) {
                        valueAccessor()(parseFloat(value));
                    }                
                },
                disposeWhenNodeIsRemoved: element 
            });
    
            ko.applyBindingsToNode(element, { value: interceptor }, context);
        }
    };
    

    示例:http://jsfiddle.net/rniemeyer/wtZ9X/

    【讨论】:

    • 您的回答将我带到 WritabledependentObservables 下的this answer,它共同回答了我的问题。谢谢
    • 快速说明:通读 Knockout 提交,我看到 RP Niemeyer 在此处引用了他自己的答案并附有快速说明:github.com/knockout/knockout/pull/1334 有一种更受支持的方式来调用 ko.bindingHandlers.value.init 行。 ..
    • 任何阅读本文的人,请注意dependentObservable() 现在称为computed()
    • 当心:在@IanYates 绑定评论的基础上。 ko 3.2.0 kbh 值打破了对更新的任何使用。 ko.bindingHandlers.value.update 调用被忽略。如果您需要更改从模型中读取的值,请使用interceptor.read 函数。例如强制返回一个字符串底层Observable().toString();
    • @RockResolve - 更新了与当前 KO 更兼容的方法。
    猜你喜欢
    • 1970-01-01
    • 2018-02-13
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多