2013-02-15 58 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") 
}