虽然 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-ishinvalid
事件过滤无效属性:
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+ 模型属性时。此外,这没有考虑必填字段的概念,我通过进行令人不快的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 插件或诸如此类的重量级解决方案。很想看看其他人正在使用什么样的模式。