Javascript 如何在主干模型中强制属性类型?
我希望有一个带有浮点属性的主干模型,但不需要太担心变量类型 我想将值解析封装在模型中,因此我考虑覆盖Javascript 如何在主干模型中强制属性类型?,javascript,backbone.js,Javascript,Backbone.js,我希望有一个带有浮点属性的主干模型,但不需要太担心变量类型 我想将值解析封装在模型中,因此我考虑覆盖set函数: var Place = Backbone.Model.extend({ set: function(attributes, options) { if (!_.isEmpty(attributes.latitude)){ attributes.latitude == parseFloat(attributes.latitude); } if (
set
函数:
var Place = Backbone.Model.extend({
set: function(attributes, options) {
if (!_.isEmpty(attributes.latitude)){
attributes.latitude == parseFloat(attributes.latitude);
}
if (!_.isEmpty(attributes.longitude)){
attributes.longitude == parseFloat(attributes.longitude);
}
Backbone.Model.prototype.set.call(this, attributes, options);
}
});
然而,这似乎很麻烦,因为我在validate方法中有类似的逻辑,并且可能在多个模型中重复。我认为视图不应该考虑这些转换
那么最好的方法是什么呢 为您的模型使用验证插件,以便您可以以通用方式验证输入 这里有几个,包括我写的一个:
错误
消息,您可以倾听并提供适当的反馈
此外,在极少数情况下,lat/lng对可以是整数,例如英格兰格林威治:0,0或北极:90180。而且由于JavaScript只有“number”,任何有效的parseFloat输入对parseInt也是有效的
但是parseFloat将始终返回一个float 我的解决方案是用预处理器代理替换主干.Model.prototype.set:
/**
* Intercept calls to Backbone.Model.set and preprocess attribute values.
*
* If the model has a <code>preprocess</code> property, that property will be
* used for mapping attribute names to preprocessor functions. This is useful
* for automatically converting strings to numbers, for instance.
*
* @param Backbone
* the global Backbone object.
*/
(function(Backbone) {
var originalSet = Backbone.Model.prototype.set;
_.extend(Backbone.Model.prototype, {
set: function(key, val, options) {
if(!this.preprocess) {
return originalSet.apply(this, arguments);
}
// If-else copied from Backbone source
if (typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
for(attr in this.preprocess) {
if(_.has(attrs, attr)) {
attrs[attr] = this.preprocess[attr](attrs[attr]);
}
}
return originalSet.call(this, attrs, options);
},
});
})(Backbone);
在此之后,具有预处理
属性的模型将使用它将属性名称映射到预处理器函数。例如,preprocess:{age:parseInt}
意味着只要设置了age
属性,值就会在实际设置之前通过parseInt
。没有相应的预处理
条目的属性将不受影响
用法示例:
var Thing = Backbone.Model.extend({
preprocess: {
mass: parseInt,
created: function(s) { return new Date(s); },
},
});
var t = new Thing({
label: '42',
mass: '42',
created: '1971-02-03T12:13:14+02:00',
});
console.log(t.get('label')+3); // 423
console.log(t.get('mass')+3); // 45
console.log(t.get('created').toLocaleString('ja-JP', { weekday: 'short' })); // 水
赞成的意见
- 该功能在所有型号中都可用,无需重复代码
- 无需在每次调用
时发送set
{validate:true}
- 无需在
中重复预处理,因为这发生在调用validate
之前(这也可能是一个con,下面的se)validate
- 主干代码的某些重复
- 可能会中断验证,因为预处理发生在调用
之前。JavaScript解析方法通常返回无效值,而不是抛出异常(即validate
返回parseInt('foo')
),因此您应该能够检测到它NaN