gpt4 book ai didi

javascript - knockout 嵌套对象范围未定义引用

转载 作者:行者123 更新时间:2023-12-02 17:18:14 25 4
gpt4 key购买 nike

我正在尝试使用 KnockoutJS 使用以下代码编写基本表单:

var Form = function() {
var self = this;
self.name = {
value: ko.observable(""),
isValid: ko.computed(function () {
return self.name.value().length > 0;
}),
},
self.email = {
value: ko.observable(""),
isValid: ko.computed(function () {
return false;
})
},
self.message = {
value: ko.observable(""),
isValid: ko.computed(function () {
return false;
})
},
self.isValid = ko.computed(function () {
return self.name.isValid && self.email.isValid && self.message.isValid;
})
};

但是,当我尝试运行此代码时,出现以下错误:无法获取未定义或 null 引用的属性“值”。对我来说,这看起来像是一个范围问题,但我对 knockout 不够熟悉,无法理解为什么会发生这种情况。如果没有 Knockout,我似乎能够使此代码正常工作(将所有可观察值替换为 true 值和 isValid 函数),但我希望实时更新这些值。我总是可以将验证函数分离到顶级函数,但这似乎是不正确的方法。每个表单字段都有一个值并且有自己独特的验证,因此使每个表单字段成为具有这两个属性的自己的对象是有意义的。

感谢任何帮助或指导。

最佳答案

这个

self.name = {
value: ko.observable(""),
isValid: ko.computed(function () {
return self.name.value().length > 0;
}),
},

不起作用,因为内部函数(计算的回调)引用了self.name,它甚至还没有完全定义。由于立即调用计算,因此您会看到错误。

可以使用deferEvaluation option延迟评估计算出的 isValid 直到某些内容实际请求其值:

self.name = {
value: ko.observable(""),
isValid: ko.computed({
read: function () { return self.name.value().length > 0; },
deferEvaluation: true
}),
},

这会起作用,但它也会很快开始变得重复和笨拙。

<小时/>

作为替代方案,您可以使用 Knockout extenders以抽象/解耦的方式使可观察的可验证的。

ko.extenders.validator = function (target, validationCallback) {
// create an isValid property on the target observable,
// immediately calculate validity of its current value
target.isValid = ko.observable(validationCallback(target()));

// subscribe to future changes
target.subscribe(function (newValue) {
target.isValid(validationCallback(newValue));
});

// return target observable for chaining
return target;
};

现在定义了这个扩展程序,您所需要做的就是创建验证值并返回 true 或 false 的回调函数。

var Form = function () {
var self = this;
self.name = ko.observable("").extend({
validator: function (value) { return value.length > 0; }
});
self.email = ko.observable("").extend({
validator: function (value) { return true; }
});
self.message = ko.observable("").extend({
validator: function (value) { return true; }
});
self.isValid = ko.computed(function () {
var overallValid = true;
ko.utils.objectForEach(self, function (key, value) {
if (value.hasOwnProperty("isValid")) {
overallValid = overallValid && value.isValid();
}
});
return overallValid;
});
};

进一步分离验证函数现在变得非常简单:

var validators = {
email: function (value) { return /* email check here */; },
minLen: function (minLen) {
return function (value) { return value.length >= minLen; }
},
maxLen: function (maxLen) {
return function (value) { return value.length <= maxLen; }
},
minmaxLen: function (minLen, maxLen) {
return function (value) { return value.length >= minLen && value.length <= maxLen; }
},
matches: function (regex) {
return function (value) { return regex.test(value); }
}
}

self.name = ko.observable("").extend({ validator: validators.minLen(1) });
self.age = ko.observable("").extend({ validator: validators.matches(/^\d+$/) });
<小时/>

你会发现当然是somebody already did all of this (以及更多)。

关于javascript - knockout 嵌套对象范围未定义引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24226711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com