10

たくさんの入力を含むフォームを検証する必要があります。また、入力が無効な場合は、特定の属性が無効であることをフォームで視覚的に示してください。このために、各フォーム要素を個別に検証する必要があります。

フォーム全体を表す1つのモデルと1つのビューがあります。属性を更新すると、次のようになります。

this.model.set('name', this.$name.val())

モデルのvalidateメソッドが呼び出されます。

ただし、そのメソッドではすべての属性を検証しているため、上記の属性を設定すると、他のすべての属性も検証され、いずれかが無効な場合はエラーが返されます。これは、私の「名前」属性が有効であっても、他の人にエラーが発生することを意味します。

では、1つの属性だけを検証するにはどうすればよいですか?

validate()メソッドで1つの属性を検証することはできないと思います。1つの解決策は、validateメソッドを使用せず、代わりに「change」イベントのすべての属性を検証することです。しかし、これにより多くの変更ハンドラーが作成されます。それは正しいアプローチですか?他に何ができますか?

また、これはバックボーンのより大きな問題を示していると思います。

model.set()モデルに属性を設定するために使用する場合は常に、検証メソッドが実行され、すべての属性が検証されます。その単一の属性を検証したいだけなので、これは直感に反しているように見えます。

4

5 に答える 5

9

Validatesilent:trueモデルを有効な状態に保つために使用されます。オプションを渡さない限り、無効な値を設定することはできません。

一度にすべての属性を設定できます。

var M=Backbone.Model.extend({
    defaults:{
        name:"",
        count:0
    },

    validate: function(attrs) {
        var invalid=[];
        if (attrs.name==="") invalid.push("name");
        if (attrs.count===0) invalid.push("count");

        if (invalid.length>0) return invalid;
    }
});

var obj=new M();
obj.on("error",function(model,err) {
    console.log(err);
});
obj.set({
    name:"name",
    count:1
});

または、設定する前に1つずつ検証します

var M=Backbone.Model.extend({
    defaults:{
        name:"",
        count:0
    },

    validate: function(attrs) {
        var invalid=[];
        if ( (_.has(attrs,"name"))&&(attrs.name==="") )
            invalid.push("name");
        if ( (_.has(attrs,"count"))&&(attrs.count===0) )
            invalid.push("count");

        if (invalid.length>0) return invalid;
    }
});

var obj=new M();
obj.on("error",function(model,err) {
    console.log(err);
});

if (!obj.validate({name:"name"}))
    obj.set({name:"name"},{silent:true});
于 2012-06-08T08:48:04.687 に答える
2

最近、小さな Backbone.js プラグイン Backbone.validateAll を作成しました。これにより、 validateAllオプションを渡すことで、現在保存/設定されているモデル属性のみを検証できます。

https://github.com/gfranko/Backbone.validateAll

于 2012-09-04T14:57:28.707 に答える
1

これはBackboneの問題ではなく、何らかの方法で検証を作成する必要はありません。モデルに保持されているすべての属性の検証には意味がありません。通常、モデルには無効な属性が含まれていませset()ん。検証が失敗しても、サイレントオプションを渡さない限り、モデルは変更されませんが、それは別の話です。ただし、この方法を選択した場合、上記の点により、検証は変更されていない属性に対して常に合格します。

別の方法を自由に選択できます。設定する属性のみを検証します(引数としてに渡されますvalidate())。

于 2012-06-08T08:23:14.967 に答える
0

モデルの set 関数を独自のカスタム関数でオーバーロードして、silent: true を渡して、検証のトリガーを回避することもできます。

set: function (key, value, options) {
    options || (options = {});
    options = _.extend(options, { silent: true });
    return Backbone.Model.prototype.set.call(this, key, value, options);
}

これは基本的にオプションで {silent:true} を渡し、Backbone.Model セット関数を {silent: true} で呼び出します。このように、 this.model.set('propertyName',val, {silent:true}) を呼び出す場所で、どこでも {silent: true} をオプションとして渡す必要はありません。

検証には、Backbone.Validation プラグインhttps://github.com/thedersen/backbone.validationも使用できます 。

于 2012-09-20T18:39:53.337 に答える
0

backbone.validation.js ファイルを変更する必要がありましたが、この作業がはるかに簡単になりました。以下のスニペットを検証関数に追加しました。

validate: function(attrs, setOptions){
            var model = this,
                opt = _.extend({}, options, setOptions);
            if(!attrs){
                return model.validate.call(model, _.extend(getValidatedAttrs(model), model.toJSON()));
            }

            ///////////BEGIN NEW CODE SNIPPET/////////////
            if (typeof attrs === 'string') {
                var attrHolder = attrs;
                attrs = [];
                attrs[attrHolder] = model.get(attrHolder);
            }
            ///////////END NEW CODE SNIPPET///////////////

            var result = validateObject(view, model, model.validation, attrs, opt);
            model._isValid = result.isValid;

            _.defer(function() {
                model.trigger('validated', model._isValid, model, result.invalidAttrs);
                model.trigger('validated:' + (model._isValid ? 'valid' : 'invalid'), model, result.invalidAttrs);
            });

            if (!opt.forceUpdate && result.errorMessages.length > 0) {
                return result.errorMessages;
            }
        }

次に、次のように単一の属性で検証を呼び出すことができます

this.model.set(attributeName, attributeValue, { silent: true });
this.model.validate(attributeName);
于 2013-04-05T17:53:35.927 に答える