Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在主干模型中强制属性类型?_Javascript_Backbone.js - Fatal编程技术网

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
    中重复预处理,因为这发生在调用
    validate
    之前(这也可能是一个con,下面的se)
欺骗
  • 主干代码的某些重复
  • 可能会中断验证,因为预处理发生在调用
    validate
    之前。JavaScript解析方法通常返回无效值,而不是抛出异常(即
    parseInt('foo')
    返回
    NaN
    ),因此您应该能够检测到它

如果您需要更轻量级的解决方案,请尝试我的小lib