2013-02-15 25 views
1

我在我的模型验证有问题。这似乎是不可能使用保存()完成(函数(){.....作为validation-这里是代码的同时。验证保存并保存()完成 - 在主干

我的模型:

App.Models.Task = Backbone.Model.extend({ 

defaults: { 

    title:'', 
    completed: 0 

}, 

validate: function (attrs, options) { 

    if(attrs.title == '' || attrs.title === undefined) { 
     return "fill title pls" 
    } 

}, 

urlRoot: 'tasks' 
}); 

和那么在我看来,我尝试将其保存在加入方法:

App.Views.TaskAdd = Backbone.View.extend({ 

tagName: 'div', 

template: template('taskTemplateAdd'), 

events : { 

    'click .addTask' : 'add' 
}, 

initialize: function() { 

    this.model.on('add',this.render, this) 


}, 

add : function() { 

    var title = $("#addNew input:eq(0)").val(); 
    var completed = $("#addNew input:eq(1)").val(); 

    this.model.set('title', title); 
    this.model.set('completed', completed); 

    this.model.save({}, 
       { 
        success: function (model, response) { 
        console.log("success"); 
       }, 
        error: function (model, response) { 
        console.log("error"); 
       } 
       }).complete(function() { 

        $("<div>Data sent</div>").dialog(); 
      $('#list').empty(); 
      }); 

}, 


render: function() { 

    this.$el.html(this.template(this.model.toJSON())); 
    return this 
} 

}); 

时验证火灾,我得到错误:

Uncaught TypeError: Object false has no method 'complete' 

我明白,这三ES可能会对返回值运行完整的回调,但如何解决这个问题?

+0

无法设置的参数是一个对象? 'this.model.set({'title',title});' – 2013-02-15 11:34:01

+0

你可以这样做:this.model.set({'title':title})或this.model.set(title,'title ') - 不能做({'title',title}); – Kriss 2013-02-15 13:22:50

回答

6

Model.save是documented如果成功或false如果不返回jqHXR对象。

因此,除非您的服务器永远不会失败,否则您需要处理save返回false的情况。这里的逻辑的一个简单的例子,你将需要:

var valid=this.model.save(); 
if(!valid) { 
    // do something when not valid 
else { 
    valid.complete(function() {}); // this is a jqHXR when valid 
} 

而且,在jQuery 1.8,使用的completedeprecated。你应该考虑使用always

+0

谢谢,我实际上改变了我的方法,现在我不需要完整。 – Kriss 2013-02-15 13:23:48

+0

这也是一个有效的选项。 :)希望你能明白为什么它没有像预期的那样工作(以及它为什么如此脆弱)。 – WiredPrairie 2013-02-15 13:28:26

0

使用。

... 
add : function() { 

var self = this; 
this.model.save({'title':$("#addNew input:eq(0)").val(),'completed':$("#addNew input:eq(1)").val()}, 
      { 
       success: function (model, response) { 
       console.log("success"); 
       self.complete(); 
      }, 
       error: function (model, response) { 
       console.log("error"); 
       self.complete(); 
      } 
      }); 

}, 

complete: function() { 

       $("<div>Data sent</div>").dialog(); 
     $('#list').empty(); 
     }, 
     ... 
+0

仍然像以前一样。 – Kriss 2013-02-15 11:24:20

+0

您可以尝试更新的解决方案。它试图在服务器响应后调用'complete'函数,即使它是错误的。 – 2013-02-15 12:07:41

+0

这正是我作为下一个解决方案所做的,但最后我改变了一种方法,并且完全不使用完成。正如WiredPraire所说,完整版从jquery的1.8版本开始折旧。 – Kriss 2013-02-15 16:01:10

0

model.save()首先执行验证(验证模型的方法)。如果成功,它会将POST/PUT发送到服务器。换句话说,如果客户端验证失败,你会得到一个错误。然后它不会发布到服务器。如果失败,则不能使用延迟对象,因为false.always()会导致错误。

另外,如果您未在model.save选项中传递wait:true,它将使用其验证的对象更新模型。我通常会通过等待:确实如此。 (我不想渲染元素两次)。

如果模型未通过客户端验证,那么它也应该失败服务器端验证。在这种情况下,有一个“无效”事件要收听。所以你只应该对成功电话感兴趣。理论上应该只是有趣的,如果它真的有更新(会触发“更改”事件)

add: { 
    var self = this; 
    this.model.on('invalid', function(error){ 
     console.log(error, 'model is invalid. Check model.validate') 
    }); 
    this.model.on('change', function(model){ 
     console.log(model.toJSON(), 'model has successfully changed') 
    }); 
    this.model.on('error', function(error){ 
     console.log("server failed to acknowledge (server connection not made)") 
    }); 
    this.model.on('sync', function(resp){ 
     console.log("server successfull acknowledged (server connection made)") 
    }); 

    this.model.save(
     { 
     title:$("#addNew input:eq(0)").val(), 
     completed:$("#addNew input:eq(1)").val() 
     }, 
     { 
     wait: true, 
     success: function (model, response) { 
      console.log("success"); 
      #fires an change event if the model is updated 
      self.complete(); 
      }, 

     error: function (model, response) { 
      console.log("error"); 
      self.complete(); 
      } 
    } 
); 
}, 
complete: function(){ 
    console.log("show this") 
}