Backbonejs collection.create: how to prevent it fr

2019-07-03 12:14发布

How can I prevent collection.create from adding items into its collection if there is an error found in the input?

html,

<div id="new-status">
      <h2>New monolog</h2>
      <form action="">
        <textarea name="content"></textarea><br>
        <input type="submit" value="Post">
      </form>
    </div>

    <div id="statuses">
      <h2>Monologs</h2>
      <ul></ul>
    </div>

backbone,

var Status = Backbone.Model.extend({
    initialize: function(){

    },
    validate: function(attrs, options) {
        if(attrs.text === '') alert("please enter some text");
    },
    url:"dummy.php",
    sync: function (method, model, options) {
        return $.ajax({
            type: "POST",
            dataType: 'json',
            url: 'server.php', 
            data: {
                text: this.get("text")
            }
        });
    }
});

var Statuses = Backbone.Collection.extend({
    model: Status
});

var NewStatusView = Backbone.View.extend({

    events: {
        "submit form": "addStatus"
    },

    initialize: function(options) {
         _.bindAll(this, 'addStatus', 'clearInput');
        this.listenTo(this.collection, 'add', this.clearInput) ;
    },

    addStatus: function(e) {
        e.preventDefault();
        this.collection.create({ text: this.$('textarea').val() });
    },

    clearInput: function() {
        this.$('textarea').val('');
    }
});

var StatusesView = Backbone.View.extend({
    initialize: function(options) {
        this.collection.on("add", this.appendStatus, this);
    },

    appendStatus: function(status) {
        this.$('ul').append('<li>' + status.escape("text") + '</li>');
    }
});

$(document).ready(function() {
    var statuses = new Statuses();
    new NewStatusView({ el: $('#new-status'), collection: statuses });
    new StatusesView({ el: $('#statuses'), collection: statuses });
});

So, when you hit the submit button without typing any text, you get an error popup from this part in the model,

validate: function(attrs, options) {
            if(attrs.text === '') alert("please enter some text");
        },

But how can I tell the collection that there is an error and do not add this empty item and also do not fire sync in the model?

EDIT:

got it worked with collection.create in this way...

model,

validate: function(attrs, options) {
    if(attrs.text === '') {
        var message = "please enter some text";
        alert(message);
        return message;
    }
},

view,

addStatus: function(e) {
        e.preventDefault();
        var one = new Status({ text: this.$('textarea').val() });

        if (!one.isValid()) {
            alert(one.validationError);
        } else {
            this.collection.create(one);
        }

    },

it seems to work fine unless it is not a good approach or against MVC pattern?

2条回答
Fickle 薄情
2楼-- · 2019-07-03 12:26

Your Model's validate method should return an error string so that models save is not fired in case of alert.

validate: function(attrs, options) {
    if(attrs.text === ''){
      alert("please enter some text");
      return "Text is empty."; // OR proper error CODE
    }
}

Check validate method of Backbone.Model.

查看更多
The star\"
3楼-- · 2019-07-03 12:35

I don't think collection.create is the right choice here.

addStatus: function(e) {
    e.preventDefault();
    var status = new Status({"text": this.$('textarea').val()})
    var error = status.valiate();
    if(!error) {
        this.collection.add(status);  
    } 
},

Also not that the backbone docs says this about validate:

If the attributes are valid, don't return anything from validate; if they are invalid, return an error of your choosing. It can be as simple as a string error message to be displayed, or a complete error object that describes the error programmatically.

So, your validate function should be fixed:

validate: function(attrs, options) {
    if(attrs.text === '') {
        var message = "please enter some text";
        alert(message);
        return message;
    }
},
查看更多
登录 后发表回答