Knockout.js 自动删除所有可观察值中的空白

Knockout.js 自动删除所有可观察值中的空白,knockout.js,Knockout.js,我在Knockout中有一个ViewModel,它主要来自映射插件(即,动态地)。这个很好用。但是,现在我的客户机希望我在提交到服务器之前确保所有输入都已删除空格。显然,修剪代码非常简单,但是对于Knockout来说相对较新,我不确定该将此代码放在哪里。我读到了,但这看起来相当冗长和重复,回到过去,并将其添加到每个可观察到的。另外,我甚至不确定我是否可以对动态生成的可观察对象(la,映射插件)这样做 是否有任何我可以扩展/覆盖的中心机制,在每次可观察到的更改时,我都可以注入一些修剪代码?基本上,

我在Knockout中有一个ViewModel,它主要来自映射插件(即,动态地)。这个很好用。但是,现在我的客户机希望我在提交到服务器之前确保所有输入都已删除空格。显然,修剪代码非常简单,但是对于Knockout来说相对较新,我不确定该将此代码放在哪里。我读到了,但这看起来相当冗长和重复,回到过去,并将其添加到每个可观察到的。另外,我甚至不确定我是否可以对动态生成的可观察对象(la,映射插件)这样做

是否有任何我可以扩展/覆盖的中心机制,在每次可观察到的更改时,我都可以注入一些修剪代码?基本上,我试图避免花费数小时检查所有表单,并在HTML中添加特殊的绑定语法(如果不需要的话)


谢谢。

您可以编写一个自定义绑定来修剪可观察的对象。类似的东西


我也有同样的问题。我编写了一个扩展,这样您就可以在视图模型中调用
trimmed
,而无需更改绑定。例如:

var vm = {
    myValue: ko.observable('').trimmed()
}
延长期限:

ko.subscribable.fn.trimmed = function() {
    return ko.computed({
        read: function() {
            return this().trim();
        },
        write: function(value) {
            this(value.trim());
            this.valueHasMutated();
        },
        owner: this
    });
};

代码中有示例。

使用Joe的解决方案作为起点,我们的实现略有不同

注意:

var vm = {
    myValue: ko.observable().trimmed()
}
ko.subscribable.fn.trimmed = function() {
    return ko.computed({
        read: function() {
            return this();
        },
        write: function(value) {
            this(value.trim());
            this.valueHasMutated();
        },
        owner: this
    });
};
  • ko.observable()
    在括号中没有任何内容
  • 新的
    trimmed
    read函数只返回
    this()
    ,不会得到任何null或未定义的异常
型号代码:

var vm = {
    myValue: ko.observable().trimmed()
}
ko.subscribable.fn.trimmed = function() {
    return ko.computed({
        read: function() {
            return this();
        },
        write: function(value) {
            this(value.trim());
            this.valueHasMutated();
        },
        owner: this
    });
};
扩展名:

var vm = {
    myValue: ko.observable().trimmed()
}
ko.subscribable.fn.trimmed = function() {
    return ko.computed({
        read: function() {
            return this();
        },
        write: function(value) {
            this(value.trim());
            this.valueHasMutated();
        },
        owner: this
    });
};

万一有人在新版的击倒游戏中遇到这个问题,当前排名靠前的答案将无法正常工作

以下是更新的和代码,用于显示所需的更改:

ko.subscribable.fn.trimmed = function() {
    return ko.computed({
       read: function() {
           return this().trim();
       },
       write: function(value) {
           this(value.trim());
           this.valueHasMutated();
       },
       owner: this
   }).extend({ notify: 'always' });
};

如果有人知道为什么现在需要扩展,请告诉我。我花了很长时间才弄明白为什么它在Knockout 3.1.0中无法正常工作。您可以创建一个自定义绑定,在内部调用
绑定,也可以在实际绑定之前将
绑定覆盖到auto trim(不推荐)

基本思想是:

  • 截取
    绑定
  • 将传递的可观测值包装在一个
    计算的
  • 使绑定从计算的而不是原始的可观察对象中读取和写入
  • 当新的输入到达时,在我们写入之前对其进行修剪
  • 当模型值更改时,修剪它并根据需要更新模型和UI
ko.bindingHandlers.trimmedValue={
init:函数(元素、valueAccessor、allBindings){
const ogValue=valueAccessor();
设newVa=valueAccessor;
//如果这是type=“text”元素且数据绑定值是可观察的,
//我们创建一个新的值访问器,它返回一个中间层
//我们的修剪
if(element.type==“text”&&ko.isObservable(ogValue)){
const trimmedValue=ko.observable().extend({“trim”:true});
//每当我们改变时,就给模型写信
trimmedValue.subscribe(ogValue);
//模型更改时更新
ogValue.subscribe(trimmedValue);
//用模型值初始化
trimmedValue(ogValue());
//从现在开始,使用trimmedValue
newVa=()=>trimmedValue;
}
//注意:您也可以使用'ko.applybindingstoode'`
返回ko.bindingHandlers.value.init(元素、newVa、allBindings)
}
}
//我们的可观测数据用于检查我们的结果
var myObs=可观察(“测试”);
myObs.subscribe(函数(newValue){
log(“更改:\”“+newValue+”\”);
});
//进行实际修剪的延长线
ko.extenders.trim=功能(目标,选项){
返回ko({
阅读:目标,
写入:函数(val){
目标(
val&&typeof val.trim==“函数”
?阀内件()
:val
);
//这确保修剪始终重置输入UI
if(val!==target.peek()){
target.valuehassmutated();
}
}
}).extend({通知:“始终”});
};
ko.applyBindings({
肌瘤
});

type=“text”trimmedValue

另一种适合我们的方法-编辑字段时进行修剪:

$(document.body).on('blur', 'input, textarea', function () { this.value = this.value.trim(); $(this).trigger('change'); });

“更改”事件的触发器确保KO获取更改(使用KO v2测试)。

虽然这可能有效,但我正在寻找一种不需要编辑HTML中所有绑定的解决方案。能否发布映射代码?您正在使用mappingOptions吗?我的映射代码只是ajax调用的
.done()
函数中的
ko.mapping.fromJS(data,{},viewmodel)
,从文档中可以添加映射选项。您可以从那里访问数据。我已经有一段时间没有处理映射选项了。var-mapping={'children':{key:function(data){return ko.utils.unwrapObservable(data.id);}}}}}var-viewModel=ko.mapping.fromJS(data,mapping);映射选项看起来很有趣,尤其是选项。然而,看起来我必须手动为每个可观察对象创建一个更新选项。我可以在映射后应用这些选项吗?如果是这样的话,我可以映射、循环并应用选项,然后重新映射,但我不知道这是否可行?您提到,在提交之前只需要对它们进行修剪。使用ko.mapping.toJS(model)取消映射您的可观察对象,然后编写一个助手递归遍历每个属性并修剪它。这很公平。也许我会试试。虽然我希望有一种方法可以在每次可观察更新时运行一些代码。FWIW,因为我正在运行输入更改的验证器,我只是在开始时运行一个trim函数。有很多很好的答案,但仍然没有一个方法可以在不检查代码和更新的情况下全面运行