简体   繁体   中英

Backbone.js model.isValid() method not returning false for an invalid model

so I am trying to get the validate from my model to actually disable the save button but to re-validate when new input is included. Anyone know the best way to attempt this. Thanks! The problem I have with my method is that once it is disabled it doesn't return in state.

Here is the main.js file

(function () {
    window.App = {
        Models: {},
        Collections: {},
        Views: {},
        Templates: {},
        Router: {}

    };

    // MODEL
    App.Models.User = Backbone.Model.extend({
        defaults: {
            firstName: 'first',
            lastName: 'last',
            email: 'Email',
            phone: '222',
            birthday: '07/22/1980'
       },

        validate: function (attrs) {

            if (!attrs.firstName) {
                return 'You must enter a real first name.';
            }
            if (!attrs.lastName) {
                return 'You must enter a real last name.';
            }
            if (attrs.email.length < 5) {
                return 'You must enter a real email.';
            }
            if (attrs.phone.toString().length < 10 ) {
                //&& attrs.phone === int
               return 'You must enter a real phone number, if you did please remove the dash and spaces.';
            }
           // if (attrs.birthday.length < 2) {
             //   return 'You must enter a real city.';
            //}
        },

        initialize: function() {
             this.on('invalid', function (model, invalid) {
                console.log(invalid);
                alert(invalid);
            });
        }

    });

    //var userModel = new App.Models.User();

    //VIEW
    App.Views.User = Backbone.View.extend({
        el: '#user',
        //model: userModel,
        //tagName: 'div',
        //id: 'user',
        //className: 'userProfile',
        //template: _.template($("#userTemplate").html()),
        //editTemplate: _.template($("#userEditTemplate").html()),


        initialize: function (){

        },

        render: function() {
            this.template = Handlebars.compile($("#userTemplate").html());
            this.editTemplate = Handlebars.compile($("#userEditTemplate").html());

            this.$el.html(this.template(this.model.toJSON()));
            return this;
        },

        events: {
            'click button.edit': 'editProfile',
            'click input.save': 'saveEdits',
            'click button.cancel': 'cancelEdits'
        },

        editProfile: function () {
            this.$el.html(this.editTemplate(this.model.toJSON()));

        }, 

        saveEdits: function () {
            var form = $(this.el).find('form#updateUser');
            this.model.set({

                firstName : form.find('.firstName').val(),
                lastName : form.find('.lastName').val(),
                email: form.find('.email').val(),
                phone: form.find('.phone').val(),
                birthday: form.find('.birthday').val()

            }, {validate: true} );

        if(!this.model.isValid()) {
            console.log('run');
            $('.save').attr("disabled", "disabled");

        } else {
            console.log('run2');
            alert('Changes have been made.');
            $('.save').removeAttr("disabled");
            return this.render();
        }


    },


        },

        cancelEdits: function() {
            this.render();
        }

    });
    //start history service
    Backbone.history.start();

    var user = new App.Views.User({model: new App.Models.User()});
    user.render();
})();

And here is the Jade File:

extends layout
block content   
    div.centerContent

        h4 User goes here with equal before it no space
            div#user
                p #{firstName} #{lastName}
                p #{email}
                p #{phone}
                p #{birthday}
                button.edit Edit

        script(id="userTemplate", type ="text/template")
                p {{firstName}} {{lastName}} 1
                p {{email}} 2 
                p {{phone}} 3 
                p {{birthday}} 4
                button.edit Edit

        script(id="userEditTemplate", type ="text/template")
            div
                form(action="#")#updateUser
                    input(type="text", class="firstName", value='{{firstName}}') 
                    input(type="text", class="lastName", value='{{lastName}}')
                    input(type="email", class="email", value='{{email}}')
                    input(type="number", class="phone",, value='{{phone}}')
                    input(type="date", class="birthday", value='{{birthday}}')
                input(type="submit", value="Save").save Save
                button.cancel Cancel
        hr
        script(type="text/javascript", src="/js/main.js")

The problem here is that you're calling the { validate: true } option to your model.set method, then you're subsequently calling model.isValid() .

When you call model.set with the validate option set to true, Backbone.js will not set the properties you pass unless they all pass validation. So, by the time you call model.isValid() the model has been changed back to the previous version (before the .set call). model.isValid() automatically calls the model.validate() method and passes the current attributes of the model to it.

In your example, the values being passed to validate by the isValid method are the current ( valid ) attributes of your model. Because of this, isValid() is always going to validate to true. Which will cause you to never reach your else clause.

The solution here is instead of calling isValid to see if your model is valid (after passing validate: true to the set method) check the value of model.validationError . If model.validationError is a truthy value, then you know your model is invalid.

Here's a JSFiddle with an example of how to do that, with some documentation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM