2012-02-20 85 views
2

所以,我可以在我編輯現有項目時進行驗證。但是,如果我想創建,驗證出於某種原因不會被啓動。相反,我看到下面的錯誤:骨幹 - 驗證不適用於創建,只更新/編輯?

//this is if the field I want to validate is empty 
Uncaught TypeError: Object #<Object> has no method 'get' 

//this is if everything in the form is filled out 
Uncaught TypeError: Cannot call method 'trigger' of undefined 

這是(我認爲是)我的js的相對部分。很抱歉,如果它的過載,我想就像我可以是儘可能具體地址:

Comic = Backbone.Model.extend({ 
    initialize: function() { 
     this.bind("error", this.notifyCollectionError); 
     this.bind("change", this.notifyCollectionChange); 
    }, 
    idAttribute: "ComicID", 
    url: function() { 
     return this.isNew() ? "/comics/create" : "/comics/edit/" + this.get("ComicID"); 
    }, 
    validate: function (atts) { 
     if ("Name" in atts & !atts.Name) { 
      return "Name is required"; 
     } 
     if ("Publisher" in atts & !atts.Publisher) { 
      return "Publisher is required"; 
     } 
    }, 
    notifyCollectionError: function (model, error) { 
     this.collection.trigger("itemError", error); 
    }, 
    notifyCollectionChange: function() { 
     this.collection.trigger("itemChanged", this); 
    } 
}); 
Comics = Backbone.Collection.extend({ 
    model: Comic, 
    url: "/comics/comics" 
}); 
comics = new Comics(); 

FormView = Backbone.View.extend({ 
    initialize: function() { 
     _.bindAll(this, "render"); 
     this.template = $("#comicsFormTemplate"); 
    }, 
    events: { 
     "change input": "updateModel", 
     "submit #comicsForm": "save" 
    }, 
    save: function() { 
     this.model.save(
      this.model.attributes, 
      { 
       success: function (model, response) { 
        model.collection.trigger("itemSaved", model); 
       }, 
       error: function (model, response) { 
        model.trigger("itemError", "There was a problem saving " + model.get("Name")); 
       } 
      } 
     ); 

     return false; 
    }, 
    updateModel: function (evt) { 
     var field = $(evt.currentTarget); 
     var data = {}; 
     var key = field.attr('ID'); 
     var val = field.val(); 
     data[key] = val; 
     if (!this.model.set(data)) { 
      //reset the form field 
      field.val(this.model.get(key)); 
     } 
    }, 
    render: function() { 
     var html = this.template.tmpl(this.model.toJSON()); 
     $(this.el).html(html); 
     $(".datepicker").datepicker(); 
     return this; 
    } 
}); 

NotifierView = Backbone.View.extend({ 
    initialize: function() { 
     this.template = $("#notifierTemplate"); 
     this.className = "success"; 
     this.message = "Success"; 
     _.bindAll(this, "render", "notifySave", "notifyError"); 
     comics.bind("itemSaved", this.notifySave); 
     comics.bind("itemError", this.notifyError); 
    }, 
    events: { 
     "click": "goAway" 
    }, 
    goAway: function() { 
     $(this.el).delay(0).fadeOut(); 
    }, 
    notifySave: function (model) { 
     this.message = model.get("Name") + " saved"; 
     this.render(); 
    }, 
    notifyError: function (message) { 

     this.message = message; 
     this.className = "error"; 
     this.render(); 
    }, 
    render: function() { 
     var html = this.template.tmpl({ message: this.message, className: this.className }); 
     $(this.el).html(html); 
     return this; 
    } 
}); 

var ComicsAdmin = Backbone.Router.extend({ 

    initialize: function() { 
     listView = new ListView({ collection: comics, el: "#comic-list" }); 
     formView = new FormView({ el: "#comic-form" }); 
     notifierView = new NotifierView({el: "#notifications" }); 
    }, 
    routes: { 
     "": "index", 
     "edit/:id": "edit", 
     "create": "create" 
    }, 
    index: function() { 
     listView.render(); 
    }, 
    edit: function (id) { 
     listView.render(); 
     $(notifierView.el).empty(); 
     $(formView.el).empty(); 
     var model = comics.get(id); 
     formView.model = model; 
     formView.render(); 
    }, 
    create: function() { 
     var model = new Comic(); 
     listView.render(); 
     $(notifierView.el).empty(); 
     $(formView.el).empty(); 
     formView.model = model; 
     formView.render(); 

    } 
}); 

jQuery(function() { 
    comics.fetch({ 

     success: function() { 
      window.app = new ComicsAdmin(); 
      Backbone.history.start(); 
     }, 
     error: function() { 

     } 
    }); 
}) 

所以,不應該我來創建得到驗證呢?爲什麼不是?

+0

您使用的骨幹版本是什麼? – ryanmarc 2012-02-20 20:42:19

+0

我有這個相同的確切問題。當執行'新模型({foo:bar})'時,驗證會運行。該模型永遠不會通過你使用的任何模型驗證傳遞「foo」。 – tkone 2012-02-22 22:19:44

+0

所以我們剛剛從0.5.3升級到0.9.1,0.9.1使用0.5.3使用的相同模型 - 初始化不會調用模型驗證。這對我來說真的很愚蠢 - 如果它不會被用到任何地方,還有什麼需要進行驗證的? – tkone 2012-02-23 18:45:49

回答

2

好的。所以,我在這裏獲得了一些溫和的成功。

首先,我寫了自己的驗證框架Backbone.Validator,因爲我不喜歡任何那些我發現的。

其次,我可以通過在new Model創建期間提供的對象中設置silent: false來獲得驗證框架以啓動驗證例程。

除了使用我的驗證框架中的use_defaults參數,我能夠在初始測試中的安裝期間覆蓋不良數據。我仍在努力對此進行更多測試,但從Chrome瀏覽器控制檯看起來好像還行。

+0

就像所有的好東西一樣,這似乎不再有效......或者它從來沒有過,而且我有一個錯誤的結果,並且太興奮了,無法想象...... – tkone 2012-02-25 19:23:04

4

創建模型的新實例時,不會調用驗證方法。根據主幹documentation,只有在設置或保存之前調用驗證。

我也與這個問題相關的問題掙扎,找到解決方案:

  • 你可以做一個新的模型,然後設置其屬性(見question 9709968
  • 更優雅的方式是調用驗證方法的初始化模型時(見question 7923074

我並不完全滿意,這些解決方案,因爲創建像骨幹documentation描述的模型的新實例當錯誤被觸發時不應該發生。不幸的是,在這兩種解決方案中,您仍然堅持使用該模型的新實例。

編輯:被模型的新實例卡住實際上相當不錯。通過這種方式,您可以向用戶反饋爲什麼它沒有通過驗證程序,並有機會糾正他/她的輸入。