虽然Backbone在模型上的内置validate()
方法对于非常简单的情况非常有效,但在处理更复杂的验证逻辑(例如必需字段)时,它很快就会崩溃。在模型上,这是我通常如何处理属性的验证:
validate: function (attrs) {
var invalid = [],
dateRegex = /^(\d{2})\/(\d{2})\/(\d{4})$/,
timeRegex = /^(\d{2}):(\d{2})$/,
isoDateTimeRegex = /^(\d{4})-(\d{1,2})-(\d{1,2})T(\d{2}):(\d{2}):(\d{2})$/;
if (_.has(attrs, "chosenScheduleDate") && !dateRegex.test(attrs.chosenScheduleDate)) {
invalid.push("chosenScheduleDate");
}
// ...some more validation rules
if (invalid.length > 0) {
return invalid;
}
},
然后,在视图中,使用new-ish invalid
事件过滤无效的属性:
modelEvents: {
"invalid": "invalidateAttributes"
},
// ...other code
invalidateAttributes: function (model, error) {
if (_.contains(error, "chosenScheduleDate")) {
this.unsetModelAttributes("chosenScheduleDate", "chosenScheduleOpenTime", "scheduleOpenTime");
this.statusNotification.show.call(this, localizedText.displayText.theSelectedDateIsInvalid, "error");
this.ui.chosenScheduleDateInput.addClass("text-input--error");
}
},
这可能会导致invalidateAttributes方法很长,特别是如果我正在验证6个以上的Model属性。此外,这没有考虑必要字段的概念,我通过做不愉快的has()
检查来处理:
if (this.model.has("scheduleOpenTime")) {
$.when(this.parent.saveAppointment.call(this))
.done(function () {
// set a new attribute on the model that represents the successfully-persisted datetime value
that.model.set("savedScheduleOpenTime", that.model.get("scheduleOpenTime"));
that.renderAppointmentForm();
});
}
然后在尝试集合期间它们无效时必须具有unset()
属性,实际上只允许在任何给定时间在模型上存在有效属性。
是否有更好,更优雅的方式来处理Backbone模型上更复杂的验证,包括必填字段?真的更喜欢简单的方法,不使用像Backbone.Validation插件或诸如此类的重量级解决方案。很想看看其他人正在使用什么样的模式。
答案 0 :(得分:1)
Addy Osmani的Backbone Fundamentals一书有关于模型属性验证的 a great section 。使用 Backbone.Validation plugin 可能是我的第一个建议,因为它很好地处理了必填字段,但您明确提到要避免这种情况。 Addy对该主题的讨论涉及一些替代方案,包括 Backbone.validateAll 插件,或专注于验证表单而非模型。