数据操作+验证的最佳实践

时间:2013-07-30 10:34:50

标签: backbone.js

我需要在我的model中存储一些数据,这些数据是Unix标准表示中的日期+次数(1970年的ms),但我所做的是通过传递像“Tue”这样的字符串来调用set 2013年7月30日12:25:43 GMT + 0200(CEST)“。字符串是我可以从view获得的字符串,我不想在我的视图中转换它,因为我认为这是model的责任。通过这种方式,功能组织良好,整洁。所以:

我把它放在我的模型中:

initialize: function() {
    var self= this;

    //conversion of the string date  into milliseconds
    this.on("change:start_time", function(model, start_time) {
        if(start_time !== null){
            var data= new Date(start_time);
            self.attributes.start_time= data.valueOf();
        }
    });
 ...

它就像一个魅力。问题是当您想要设置start_time属性并同时从我的view之一验证它时:

this.model.set({
    start_time: startDatePicker.getLocalDate()
}, {validate : true});

这里有什么问题? 在触发初始化时设置的事件处理程序之前执行验证。我找到了一个解决方法:将转换转换为新函数,并在.on和验证中调用它。但我认为更整洁的东西是可能的。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

start_time事件被触发之前,将验证值change。另外,如果您不希望触发model.attributes事件,则不建议直接设置set,而是使用{silent:true}并传递change

我建议使用以下方法之一并删除您的事件处理程序。

在调用set:

之前进行转换
var dt = new Date(startDatePicker.getLocalDate()).valueOf();
this.model.set({
   start_time: dt
 }, {validate : true});

如果您坚持让您的模型进行转换,则另一个选项会覆盖模型中的set方法:

var Model = Backbone.Model.extend({
  set:function(key,val,options) {
    var attrs;

    // from Backbone source
    if (typeof key === 'object') {
      attrs = key;
      options = val;
    } else {
      (attrs = {})[key] = val;
    }

    if (attrs['start_time'])
      attrs['start_time'] = new Date(attrs['start_name']).valueOf();

    Backbone.Model.prototype.set.call(this,attrs,options);
 }
 // your existing code 
});

就个人而言,我会选择第一种方法。