使用 Backbone 验证插件选择性地验证模型属性?
Selectively validate model attributes using Backbone Validation plugin?
我正在使用 Backbone Validation plugin 并希望在不同时间选择性地验证不同的模型属性集,这可能吗?
我的测试模型对 name
、age
和 address
进行了验证,如果我只想验证 address
,我该怎么做?
我认为这是调用 this.model.validate('address');
的情况,但所有验证规则似乎 运行?
JS
console.clear();
const Model = Backbone.Model.extend({
validation: {
name: {
required: true
},
age: {
range: [1, 80],
required: true
},
address: {
minLength: 1,
msg: 'Address required',
required: false
}
}
});
const View = Backbone.View.extend({
template: Handlebars.compile( $('.tmpl-person').html() ),
className: 'view',
events: {
'click .js-action--validate-keys': 'actionValidateKeysClicked',
'click .js-action--validate-key': 'actionValidateKeyClicked'
},
initialize() {
Backbone.Validation.bind(this);
this.listenTo(this.model, 'validated', this.onModelValidated, this);
this.listenTo(this.model, 'validated:valid', this.onModelValid, this);
this.listenTo(this.model, 'validated:invalid', this.onModelInvalid, this);
},
render() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
actionValidateKeysClicked(event) {
event.preventDefault();
console.log('actionValidateKeysClicked');
this.model.set({
'name': 'Joe Bloggs',
'age': 23
});
this.model.validate(['name', 'age']);
},
actionValidateKeyClicked(event) {
event.preventDefault();
console.log('actionValidateKeyClicked');
this.model.set('address', '123 ABC');
this.model.validate('address');
},
/**
* The validated event is triggered after validation is performed, either it was successful or not.
* isValid is true or false depending on the result of the validation.
*/
onModelValidated(isValid, model, errors) {
console.log('onModelValidated', isValid, model, errors);
},
onModelValid(model) {
console.log('onModelValid', model);
},
onModelInvalid(model, errors) {
console.log('onModelInvalid', model, errors);
}
});
const newModel = new Model();
const newView = new View({
model: newModel
});
document.body.append(newView.render().el);
JSfiddle http://jsfiddle.net/kyllle/qmx2y9yr/
isValid
要仅验证某些字段,Backbone.Validation offers a modified version of isValid
。
If you pass the name of an attribute or an array of names, you can
check whether or not the attributes are valid:
// Check if name is valid
var isValid = model.isValid('name');
// Check if name and age are valid
var isValid = model.isValid(['name', 'age']);
isValid
将仅在验证出现错误时触发 'invalid'
事件 (source),而不会触发 'validated'
事件或 'validated:valid'
.
preValidate
Sometimes it can be useful to check (for instance on each key press)
if the input is valid - without changing the model - to perform some
sort of live validation. You can execute the set of validators for an
attribute, or a hash of attributes, by calling the preValidate
method and pass it the name of the attribute and the value to
validate, or a hash of attributes.
If the value is not valid, the error message is returned (truthy),
otherwise it returns a falsy value.
// Validate one attribute
// The `errorsMessage` returned is a string
var errorMessage = model.preValidate('attributeName', 'Value');
// Validate a hash of attributes
// The errors object returned is a key/value pair of attribute name/error, e.g
// {
// name: 'Name is required',
// email: 'Email must be a valid email'
// }
var errors = model.preValidate({name: 'value', email: 'foo@example.com'});
演示
我拿了你的代码在下面做了一个小例子来演示使用isValid
时不触发无效事件,但使用validate
时会触发。另外,请注意 preValidate
.
不会触发任何事件
const Model = Backbone.Model.extend({
validation: {
name: {
required: true
},
age: {
range: [1, 80],
required: true
},
address: {
minLength: 1,
msg: 'Address required',
required: true
}
}
});
const View = Backbone.View.extend({
template: $('.tmpl-person').html(),
className: 'view',
events: {
'click .validate': 'onValidateClick',
'click .is-valid': 'onIsValidClick',
'click .pre-validate': 'onPreValidateClick',
},
initialize() {
Backbone.Validation.bind(this);
this.listenTo(this.model, {
'all': this.onAllModelEvent,
// 'validated': this.onModelValidated,
// 'validated:valid': this.onModelValid,
// 'validated:invalid': this.onModelInvalid
});
},
render() {
this.$el.html(this.template);
this.$checkbox = this.$('.invalid');
return this;
},
getAddress() {
return this.$checkbox.is(':checked') ? null : '123 ABC';
},
onValidateClick() {
console.log('validate click');
this.model.set('address', this.getAddress());
console.log("validate:", this.model.validate('address'));
},
onIsValidClick() {
console.log('isValid click');
this.model.set('address', this.getAddress());
console.log("isValid:", this.model.isValid('address'));
},
onPreValidateClick() {
console.log('preValidate click');
this.model.set('address', this.getAddress());
console.log("preValidate:", this.model.preValidate('address'));
},
onAllModelEvent: function(event) {
console.log("event:", event);
}
});
const newModel = new Model();
const newView = new View({
model: newModel
});
document.body.append(newView.render().el);
* {
-webkit-font-smoothing: antialiased;
}
body {
padding: 5%;
font-size: 16px;
line-height: 1.4;
}
.view {
width: 100%;
height: 100vh;
background: lightBlue;
}
.btn {
outline: none;
border: none;
background: #1C90F3;
border-radius: 4px;
color: white;
padding: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.validation/0.11.5/backbone-validation-min.js"></script>
<script type="text/template" class="tmpl-person">
Set 'address' and use:
<button type="button" class="btn validate">validate</button>
<button type="button" class="btn is-valid">isValid</button>
<button type="button" class="btn pre-validate">preValidate</button>
<br>
<input type="checkbox" class="invalid">make address invalid.
</script>
附加信息
旁注
请注意我是如何对一个对象使用 listenTo
而不是调用它 3 次。
this.listenTo(this.model, {
'validated': this.onModelValidated,
'validated:valid': this.onModelValid,
'validated:invalid': this.onModelInvalid
});
此外,没有 this
参数传递给 listenTo
,这可能与旧的 on
/bind
语法混淆。
我正在使用 Backbone Validation plugin 并希望在不同时间选择性地验证不同的模型属性集,这可能吗?
我的测试模型对 name
、age
和 address
进行了验证,如果我只想验证 address
,我该怎么做?
我认为这是调用 this.model.validate('address');
的情况,但所有验证规则似乎 运行?
JS
console.clear();
const Model = Backbone.Model.extend({
validation: {
name: {
required: true
},
age: {
range: [1, 80],
required: true
},
address: {
minLength: 1,
msg: 'Address required',
required: false
}
}
});
const View = Backbone.View.extend({
template: Handlebars.compile( $('.tmpl-person').html() ),
className: 'view',
events: {
'click .js-action--validate-keys': 'actionValidateKeysClicked',
'click .js-action--validate-key': 'actionValidateKeyClicked'
},
initialize() {
Backbone.Validation.bind(this);
this.listenTo(this.model, 'validated', this.onModelValidated, this);
this.listenTo(this.model, 'validated:valid', this.onModelValid, this);
this.listenTo(this.model, 'validated:invalid', this.onModelInvalid, this);
},
render() {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
actionValidateKeysClicked(event) {
event.preventDefault();
console.log('actionValidateKeysClicked');
this.model.set({
'name': 'Joe Bloggs',
'age': 23
});
this.model.validate(['name', 'age']);
},
actionValidateKeyClicked(event) {
event.preventDefault();
console.log('actionValidateKeyClicked');
this.model.set('address', '123 ABC');
this.model.validate('address');
},
/**
* The validated event is triggered after validation is performed, either it was successful or not.
* isValid is true or false depending on the result of the validation.
*/
onModelValidated(isValid, model, errors) {
console.log('onModelValidated', isValid, model, errors);
},
onModelValid(model) {
console.log('onModelValid', model);
},
onModelInvalid(model, errors) {
console.log('onModelInvalid', model, errors);
}
});
const newModel = new Model();
const newView = new View({
model: newModel
});
document.body.append(newView.render().el);
JSfiddle http://jsfiddle.net/kyllle/qmx2y9yr/
isValid
要仅验证某些字段,Backbone.Validation offers a modified version of isValid
。
If you pass the name of an attribute or an array of names, you can check whether or not the attributes are valid:
// Check if name is valid var isValid = model.isValid('name'); // Check if name and age are valid var isValid = model.isValid(['name', 'age']);
isValid
将仅在验证出现错误时触发 'invalid'
事件 (source),而不会触发 'validated'
事件或 'validated:valid'
.
preValidate
Sometimes it can be useful to check (for instance on each key press) if the input is valid - without changing the model - to perform some sort of live validation. You can execute the set of validators for an attribute, or a hash of attributes, by calling the
preValidate
method and pass it the name of the attribute and the value to validate, or a hash of attributes.If the value is not valid, the error message is returned (truthy), otherwise it returns a falsy value.
// Validate one attribute // The `errorsMessage` returned is a string var errorMessage = model.preValidate('attributeName', 'Value'); // Validate a hash of attributes // The errors object returned is a key/value pair of attribute name/error, e.g // { // name: 'Name is required', // email: 'Email must be a valid email' // } var errors = model.preValidate({name: 'value', email: 'foo@example.com'});
演示
我拿了你的代码在下面做了一个小例子来演示使用isValid
时不触发无效事件,但使用validate
时会触发。另外,请注意 preValidate
.
const Model = Backbone.Model.extend({
validation: {
name: {
required: true
},
age: {
range: [1, 80],
required: true
},
address: {
minLength: 1,
msg: 'Address required',
required: true
}
}
});
const View = Backbone.View.extend({
template: $('.tmpl-person').html(),
className: 'view',
events: {
'click .validate': 'onValidateClick',
'click .is-valid': 'onIsValidClick',
'click .pre-validate': 'onPreValidateClick',
},
initialize() {
Backbone.Validation.bind(this);
this.listenTo(this.model, {
'all': this.onAllModelEvent,
// 'validated': this.onModelValidated,
// 'validated:valid': this.onModelValid,
// 'validated:invalid': this.onModelInvalid
});
},
render() {
this.$el.html(this.template);
this.$checkbox = this.$('.invalid');
return this;
},
getAddress() {
return this.$checkbox.is(':checked') ? null : '123 ABC';
},
onValidateClick() {
console.log('validate click');
this.model.set('address', this.getAddress());
console.log("validate:", this.model.validate('address'));
},
onIsValidClick() {
console.log('isValid click');
this.model.set('address', this.getAddress());
console.log("isValid:", this.model.isValid('address'));
},
onPreValidateClick() {
console.log('preValidate click');
this.model.set('address', this.getAddress());
console.log("preValidate:", this.model.preValidate('address'));
},
onAllModelEvent: function(event) {
console.log("event:", event);
}
});
const newModel = new Model();
const newView = new View({
model: newModel
});
document.body.append(newView.render().el);
* {
-webkit-font-smoothing: antialiased;
}
body {
padding: 5%;
font-size: 16px;
line-height: 1.4;
}
.view {
width: 100%;
height: 100vh;
background: lightBlue;
}
.btn {
outline: none;
border: none;
background: #1C90F3;
border-radius: 4px;
color: white;
padding: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.validation/0.11.5/backbone-validation-min.js"></script>
<script type="text/template" class="tmpl-person">
Set 'address' and use:
<button type="button" class="btn validate">validate</button>
<button type="button" class="btn is-valid">isValid</button>
<button type="button" class="btn pre-validate">preValidate</button>
<br>
<input type="checkbox" class="invalid">make address invalid.
</script>
附加信息
旁注
请注意我是如何对一个对象使用 listenTo
而不是调用它 3 次。
this.listenTo(this.model, {
'validated': this.onModelValidated,
'validated:valid': this.onModelValid,
'validated:invalid': this.onModelInvalid
});
此外,没有 this
参数传递给 listenTo
,这可能与旧的 on
/bind
语法混淆。