使用Backbone Validation插件有选择地验证模型属性?

时间:2017-01-31 20:56:45

标签: javascript validation backbone.js backbone.validation.js

我使用Backbone Validation plugin并希望在不同时间有选择地验证不同的模型属性集,这可能吗?

我的测试模型已对nameageaddress进行了验证,如果我只想验证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/

1 个答案:

答案 0 :(得分:1)

isValid

要仅验证某些字段,Backbone.Validation会提供isValid的修改版本。

  

如果传递属性名称或名称数组,则可以   检查属性是否有效:

// 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'事件或{{1 }}

'validated:valid'

  

有时候检查是有用的(例如每次按键时)   如果输入有效 - 不更改模型 - 执行一些   一种实时验证。您可以执行一组验证器   属性或属性的哈希,通过调用preValidate   方法并将属性的名称和值传递给它   验证,或属性的哈希。

     

如果该值无效,则返回错误消息(真实),   否则它会返回一个假值。

preValidate

演示

我拿了你的代码并在下面做了一个小例子,以证明在使用// 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>与对象一起使用而不是将其调用3次。

listenTo

此外,没有this.listenTo(this.model, { 'validated': this.onModelValidated, 'validated:valid': this.onModelValid, 'validated:invalid': this.onModelInvalid }); 参数传递给this,这可能与旧的listenTo / on语法混淆。