删除无效值.骨干validate()



我的例子:

var UserModel = Backbone.Model.extend({
   validate: function(attrs) {
        if (attrs.color  == 'muave') {
      return true; 
    }
  }
});
var me = new UserModel({ id: '123', silent: true });
me.on('invalid', function (model, error) {
  console.log('event invalid')
});

me.set('color', 'muave');
me.set('name', 'sasha');

if(!me.isValid()){
   me.clear()
}

我不想清理所有的模型/只有那些没有通过验证的属性。有可能吗?

thank you very much

乌利希期刊指南:我不知道我做得有多好?

var UserModel = Backbone.Model.extend({
    validate_prop :['color','name'],
   validate: function(attrs) {
        if (attrs.color  == 'muave' || attrs.name == 'sasha') {
      return true;
      }
    },
    positiveValid: function(){
        for(var i = 0 ;i< this.validate_prop.length;i++){
             this.unset(this.validate_prop[i])
        }
    }

});
var me = new UserModel({ id: '123', silent: true });
me.on('invalid', function (model, error) {
  console.log('event invalid')
});
me.set('color', 'muave');
me.set('name', 'sasha');
if(!me.isValid()){
 me.positiveValid(); 
 me.isValid() //clear validationError: true
}

也许有一个更普遍的解决方案?谢谢你的帮助。

这大致是我将如何去做(注意这是伪代码,我可能有一个错误在那里):

// An object of validation rules
validation: {
    color: {
        type: 'String',
        options: {
            notEqualTo: 'muave'
        }
    },
    name: {
        type: 'String',
        options: {
            notEqualTo: 'sasha'
        }
    },
},
initialize: function () {
    this.validation = validation || {};
},
validate: function (attrs) {
    this.invalidAttrs = {};
    // Loop through validation object, return the first invalid attribute.
    var invalid = _.find(this.validation, function (options, attr) {
        var type = attr.type || 'String';
        return this['validate' + attr.type](attr, options);
    }, this);
    // If there was an invalid attribute add it invalidAttrs.
    // Also trigger an event.. could be useful.
    if (invalid) {
        this.invalidAttrs[attr] = invalid;
        this.trigger('invalid:' + attr, invalid);
    }
    return invalid;
},
validateString: function (attr, options) {
    if (options.notEqualTo && this.get(attr) === options.notEqualTo) {
        return {
            'String cannot be equal to ' + options.notEqualTo
        };
    }
}

那么你可以这样做:

if(!me.isValid()){
   _.each(me.invalidAttrs, function(reason, attr) {
        me.unset(attr);
   });
}

这只会找到错误然后停止,您可以很容易地更改它以累积所有错误。最基本的是,你有一个validation对象,你循环通过它,它有模型的验证规则。当你在那个对象中说type: 'Number'时,它会调用validateNumber(attr, options)来确定一个数字是否有效。我还建议为所有类型添加required: true/false

下面是我刚才所说的一个更复杂和真实的例子:

////////////////
// Validation //
////////////////
/**
 * Syntax for validation rules
 * @type {Object|Function}
 * validation: {
 *     <attributeNameA>: {
 *         required: false, // default, can be omitted
 *         type: 'string', // default, can be omitted
 *         options: {
 *             // type-specific validation rules, see validator
 *             // documentation
 *         }
 *     },
 *     <attributeNameB>: {
 *         validator: function (value, attrs) {
 *             // optional custom validator, validated first if present
 *         },
 *         required: true, // validated second if present
 *         type: 'date', // type validation is validated last
 *         options: {
 *             // type-specific validation rules
 *         }
 *     }
 * }
 */
/**
 * Validate model
 * @param  {Object} attrs   attributes
 * @param  {Object} options options
 * @return {Object|undefined}         returns validation error object
 *                                            or undefined if valid
 */
validate: function(attrs, options) {
    if (!this.validation) {
        return;
    }
    options = options || {};
    var invalidAttrs = {},
        validAttrs = {},
        isValid = true,
        isPartial,
        validation = _.result(this, 'validation');
    function checkValidity(rule, attr) {
        /* jshint validthis:true */
        var error = rule && this.validateAttr(rule, attr, attrs[attr], options);
        if (error) {
            invalidAttrs[attr] = error;
            isValid = false;
        } else if(rule) {
            validAttrs[attr] = true;
        }
    }
    if (options.validateAttr) {
        var attr = options.validateAttr;
        checkValidity.call(this, validation[attr], attr);
        this.attrState = this.attrState || {};
        this.attrState[attr] = isValid;
        isPartial = _.difference(_.keys(validation), _.keys(this.attrState)).length > 0;
    } else {
        _.each(validation, checkValidity, this);
    }
    if (!options.silent) {
        isValid = options.validateAttr ? _.all(this.attrState) : isValid;
        this.triggerValidationEvents(isValid, validAttrs, invalidAttrs, isPartial);
    }
    // Note: successful validation needs to return undefined / falsy
    return isValid ? void 0 : invalidAttrs;
},
/**
 * Validate attribute with a given value
 * @param  {Object} rule    validation rule from validation object
 * @param  {String} attr    attribute name
 * @param  {Mixed} value   value
 * @param  {Object} options options
 * @return {Object|undefined}         returns validation error object
 *                                            or undefined if valid
 */
validateAttr: function(rule, attr, value, options) {
    var error;
    options = _.extend({}, options, rule.options);
    if (rule.required && (value == null || value === '')) {
        return {
            reasonCode: 'required'
        };
    }
    if (rule.type) {
        if (!this['validate' + rule.type]) {
            console.error('No validation found for type:', rule.type);
        }
        error = this['validate' + rule.type].call(this, value, options);
        if (error) {
            return error;
        }
    }
    if (rule.validator) {
        return rule.validator.call(this, value, options);
    }
},
/**
 * Convenience method: check if a single attribute is valid
 * @param  {String}  attr attribute name to be validated
 * @return {Boolean}      true if valid
 */
isValidAttr: function(attr, value, options) {
    var obj = {};
    obj[attr] = value;
    var attrs = _.extend({}, this.attributes, obj);
    var error = this.validate(attrs, _.extend({}, options, {
        validateAttr: attr
    }));
    if (error) {
        this.validationError = this.validationError || {};
        this.validationError[attr] = error;
    } else if (this.validationError && attr in this.validationError) {
        delete this.validationError[attr];
    }
    return error === void 0;
},
/**
 * Triggers events for valid and invalid attributes after validation
 * @param {Boolean} isValid      was validation successful?
 * @param {Object}  validAttrs   attributes that were validated successfully.
 * @param {Object}  invalidAttrs attributes for which validation failed.
 * @param  {Boolean} isPartial    is it validating only a part of the model?
 */
triggerValidationEvents: function(isValid, validAttrs, invalidAttrs, isPartial) {
    if (!isPartial) {
        this.trigger('validated', isValid, this, invalidAttrs);
        this.trigger('validated:' + (isValid ? 'valid' : 'invalid'), this, invalidAttrs);
    }
    _.each(validAttrs, function(value, attr) {
        this.trigger('validated:' + attr, this, true);
    }, this);
    _.each(invalidAttrs, function(error, attr) {
        this.trigger('validated:' + attr, this, false, error);
    }, this);
}

最新更新