Backbone.js モデルの検証メソッドを定義しました。問題は、検証が失敗した (つまり、Model.validate メソッドが値を返した) 場合でも、post/put 要求がサーバーに送信されることです。これは、Backbone.js のドキュメントで説明されている内容と矛盾しています。私は自分が間違っていることを理解できません。
モデルの定義は次のとおりです。
/**
* Model - Contact
*/
var Contact = Backbone.Model.extend({
urlRoot: '/contacts.json',
idAttribute: '_id',
defaults: function() {
return {
surname: '',
given_name: '',
org: '',
phone: new Array(),
email: new Array(),
address: new Array({
street: '',
district: '',
city: '',
country: '',
postcode: ''
})
};
}
validate: function(attributes) {
if (typeof attributes.validationDisabled === 'undefined') {
var errors = new Array();
// Validate surname.
if (_.isEmpty(attributes.surname) === true) {
errors.push({
type: 'form',
attribute: 'surname',
message: 'Please enter a surname.'
});
}
// Validate emails.
if (_.isEmpty(attributes.email) === false) {
var emailRegex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,6}$/i;
// Stores indexes of email values which fail validation.
var emailIndex = new Array();
_.each(attributes.email, function(email, index) {
if (emailRegex.test(email.value) === false) {
emailIndex.push(index);
}
});
// Create error message.
if (emailIndex.length > 0) {
errors.push({
type: 'form',
attribute: 'email',
index: emailIndex,
message: 'Please enter valid email address.'
});
}
}
if (errors.length > 0) {
console.log('Form validation failed.');
return errors;
}
}
}
});
Model.save() メソッドを呼び出すビューを次に示します (以下のメソッド saveContact() を参照)。簡潔にするために、このビューに属する他のメソッドは以下に含まれていないことに注意してください。
/**
* View - Edit contact form
*/
var EditContactFormView = Backbone.View.extend({
initialize: function() {
_.bindAll(this, 'createDialog', 'formError', 'render', 'saveContact', 'updateContact');
// Add templates.
this._editFormTemplate = _.template($('#edit-contact-form-tpl').html());
this._emailFieldTemplate = _.template($('#email-field-tpl').html());
this._phoneFieldTemplate = _.template($('#phone-field-tpl').html());
// Get URI of current page.
this.currentPageUri = this.options.currentPageUri;
// Create array to hold references to all subviews.
this.subViews = new Array();
// Set options for new or existing contact.
this.model = this.options.model;
// Bind with Model validation error event.
this.model.on('error', this.formError);
this.render();
}
/**
* Deals with form validation errors
*/
formError: function(model, error) {
console.log(error);
},
saveContact: function(event) {
var self = this;
// Prevent submit event trigger from firing.
event.preventDefault();
// Trigger form submit event.
eventAggregator.trigger('submit:contactEditForm');
// Update model with form values.
this.updateContact();
// Enable validation for Model. Done by unsetting validationDisabled
// attribute. This setting was formerly applied to prevent validation
// on Model.fetch() events. See this.model.validate().
this.model.unset('validationDisabled');
// Save contact to database.
this.model.save(this.model.attributes, {
success: function(model, response) {
if (typeof response.flash !== 'undefined') {
Messenger.trigger('new:messages', response.flash);
}
},
error: function(model, response) {
console.log(response);
throw error = new Error('Error occured while trying to save contact.');
},
wait: true
});
},
/**
* Extract form values and update Contact.
*/
updateContact: function() {
this.model.set('surname', this.$('#surname-field').val());
this.model.set('given_name', this.$('#given-name-field').val());
this.model.set('org', this.$('#org-field').val());
// Extract address form values.
var address = new Array({
street: this.$('input[name="street"]').val(),
district: this.$('input[name="district"]').val(),
city: this.$('input[name="city"]').val(),
country: this.$('input[name="country"]').val(),
postcode: this.$('input[name="postcode"]').val()
});
this.model.set('address', address);
}
});