Backbone - 验证不适用于创建,只能更新/编辑?

发布于 2025-01-07 12:03:36 字数 4579 浏览 2 评论 0原文

因此,当我编辑现有项目时,我能够很好地进行验证。但是,如果我想创建,由于某种原因验证不会启动。相反,我看到以下错误:

//this is if the field I want to validate is empty
Uncaught TypeError: Object #<Object> has no method 'get'

//this is if everything in the form is filled out
Uncaught TypeError: Cannot call method 'trigger' of undefined

这是(我认为是)我的 js 的相对部分。抱歉,如果它是一个过载,我想添加尽可能多的内容以尽可能具体:

Comic = Backbone.Model.extend({
    initialize: function () {
        this.bind("error", this.notifyCollectionError);
        this.bind("change", this.notifyCollectionChange);
    },
    idAttribute: "ComicID",
    url: function () {
        return this.isNew() ? "/comics/create" : "/comics/edit/" + this.get("ComicID");
    },
    validate: function (atts) {
        if ("Name" in atts & !atts.Name) {
            return "Name is required";
        }
        if ("Publisher" in atts & !atts.Publisher) {
            return "Publisher is required";
        }
    },
    notifyCollectionError: function (model, error) {
        this.collection.trigger("itemError", error);
    },
    notifyCollectionChange: function () {
        this.collection.trigger("itemChanged", this);
    }
});
Comics = Backbone.Collection.extend({
    model: Comic,
    url: "/comics/comics"
});
comics = new Comics();

FormView = Backbone.View.extend({
    initialize: function () {
        _.bindAll(this, "render");
        this.template = $("#comicsFormTemplate");
    },
    events: {
        "change input": "updateModel",
        "submit #comicsForm": "save"
    },
    save: function () {
        this.model.save(
            this.model.attributes,
            {
                success: function (model, response) {
                    model.collection.trigger("itemSaved", model);
                },
                error: function (model, response) {
                    model.trigger("itemError", "There was a problem saving " + model.get("Name"));
                }
            }
        );

        return false;
    },
    updateModel: function (evt) {
        var field = $(evt.currentTarget);
        var data = {};
        var key = field.attr('ID');
        var val = field.val();
        data[key] = val;
        if (!this.model.set(data)) {
            //reset the form field
            field.val(this.model.get(key));
        }
    },
    render: function () {
        var html = this.template.tmpl(this.model.toJSON());
        $(this.el).html(html);
        $(".datepicker").datepicker();
        return this;
    }
});

NotifierView = Backbone.View.extend({
    initialize: function () {
        this.template = $("#notifierTemplate");
        this.className = "success";
        this.message = "Success";
        _.bindAll(this, "render", "notifySave", "notifyError");
        comics.bind("itemSaved", this.notifySave);
        comics.bind("itemError", this.notifyError);
    },
    events: {
        "click": "goAway"
    },
    goAway: function () {
        $(this.el).delay(0).fadeOut();
    },
    notifySave: function (model) {
        this.message = model.get("Name") + " saved";
        this.render();
    },
    notifyError: function (message) {

        this.message = message;
        this.className = "error";
        this.render();
    },
    render: function () {
        var html = this.template.tmpl({ message: this.message, className: this.className });
        $(this.el).html(html);
        return this;
    }
});

var ComicsAdmin = Backbone.Router.extend({

    initialize: function () {
        listView = new ListView({ collection: comics, el: "#comic-list" });
        formView = new FormView({ el: "#comic-form" });
        notifierView = new NotifierView({el: "#notifications" });
    },
    routes: {
        "": "index",
        "edit/:id": "edit",
        "create": "create"
    },
    index: function () {
        listView.render();
    },
    edit: function (id) {
        listView.render();
        $(notifierView.el).empty();
        $(formView.el).empty();
        var model = comics.get(id);
        formView.model = model;
        formView.render();
    },
    create: function () {
        var model = new Comic();
        listView.render();
        $(notifierView.el).empty();
        $(formView.el).empty();
        formView.model = model;
        formView.render();

    }
});

jQuery(function () {
    comics.fetch({

        success: function () {
            window.app = new ComicsAdmin();
            Backbone.history.start();
        },
        error: function () {

        }
    });
})

那么,我的创建不应该也得到验证吗?为什么不是呢?

So, I am able to validate just fine when I am editing an existing item. However, if I want to create, validation for some reason is not getting kicked off. Instead, I am seeing the errors below:

//this is if the field I want to validate is empty
Uncaught TypeError: Object #<Object> has no method 'get'

//this is if everything in the form is filled out
Uncaught TypeError: Cannot call method 'trigger' of undefined

Here is(what I think is) the relative portion of my js. Sorry if its an overload, I wanted to add as much as I can to be as specific as possible:

Comic = Backbone.Model.extend({
    initialize: function () {
        this.bind("error", this.notifyCollectionError);
        this.bind("change", this.notifyCollectionChange);
    },
    idAttribute: "ComicID",
    url: function () {
        return this.isNew() ? "/comics/create" : "/comics/edit/" + this.get("ComicID");
    },
    validate: function (atts) {
        if ("Name" in atts & !atts.Name) {
            return "Name is required";
        }
        if ("Publisher" in atts & !atts.Publisher) {
            return "Publisher is required";
        }
    },
    notifyCollectionError: function (model, error) {
        this.collection.trigger("itemError", error);
    },
    notifyCollectionChange: function () {
        this.collection.trigger("itemChanged", this);
    }
});
Comics = Backbone.Collection.extend({
    model: Comic,
    url: "/comics/comics"
});
comics = new Comics();

FormView = Backbone.View.extend({
    initialize: function () {
        _.bindAll(this, "render");
        this.template = $("#comicsFormTemplate");
    },
    events: {
        "change input": "updateModel",
        "submit #comicsForm": "save"
    },
    save: function () {
        this.model.save(
            this.model.attributes,
            {
                success: function (model, response) {
                    model.collection.trigger("itemSaved", model);
                },
                error: function (model, response) {
                    model.trigger("itemError", "There was a problem saving " + model.get("Name"));
                }
            }
        );

        return false;
    },
    updateModel: function (evt) {
        var field = $(evt.currentTarget);
        var data = {};
        var key = field.attr('ID');
        var val = field.val();
        data[key] = val;
        if (!this.model.set(data)) {
            //reset the form field
            field.val(this.model.get(key));
        }
    },
    render: function () {
        var html = this.template.tmpl(this.model.toJSON());
        $(this.el).html(html);
        $(".datepicker").datepicker();
        return this;
    }
});

NotifierView = Backbone.View.extend({
    initialize: function () {
        this.template = $("#notifierTemplate");
        this.className = "success";
        this.message = "Success";
        _.bindAll(this, "render", "notifySave", "notifyError");
        comics.bind("itemSaved", this.notifySave);
        comics.bind("itemError", this.notifyError);
    },
    events: {
        "click": "goAway"
    },
    goAway: function () {
        $(this.el).delay(0).fadeOut();
    },
    notifySave: function (model) {
        this.message = model.get("Name") + " saved";
        this.render();
    },
    notifyError: function (message) {

        this.message = message;
        this.className = "error";
        this.render();
    },
    render: function () {
        var html = this.template.tmpl({ message: this.message, className: this.className });
        $(this.el).html(html);
        return this;
    }
});

var ComicsAdmin = Backbone.Router.extend({

    initialize: function () {
        listView = new ListView({ collection: comics, el: "#comic-list" });
        formView = new FormView({ el: "#comic-form" });
        notifierView = new NotifierView({el: "#notifications" });
    },
    routes: {
        "": "index",
        "edit/:id": "edit",
        "create": "create"
    },
    index: function () {
        listView.render();
    },
    edit: function (id) {
        listView.render();
        $(notifierView.el).empty();
        $(formView.el).empty();
        var model = comics.get(id);
        formView.model = model;
        formView.render();
    },
    create: function () {
        var model = new Comic();
        listView.render();
        $(notifierView.el).empty();
        $(formView.el).empty();
        formView.model = model;
        formView.render();

    }
});

jQuery(function () {
    comics.fetch({

        success: function () {
            window.app = new ComicsAdmin();
            Backbone.history.start();
        },
        error: function () {

        }
    });
})

So, shouldnt my create be getting validated too? Why isnt it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野稚 2025-01-14 12:03:36

创建模型的新实例时,不会调用 validate 方法。根据主干文档,验证仅在设置或保存之前调用。

我也在努力解决这个问题,并在相关问题中找到了解决方案:

  • 您可以制作一个新模型,然后设置其属性(请参阅问题9709968< /a>)
  • 更优雅的方法是在初始化模型时调用 validate 方法(参见 问题 7923074

我对这些解决方案并不完全满意,因为创建了模型的新实例,如主干中所述文档。不幸的是,在这两种解决方案中,您仍然停留在模型的新实例上。

编辑:坚持使用模型的新实例实际上非常好。通过这种方式,您可以向用户提供有关其未通过验证器的原因的反馈,并提供纠正他/她的输入的机会。

When creating a new instance of a model, the validate method isn't called. According to the backbone documentation the validation is only called before set or save.

I am also struggling with this problem and found solutions in related questions:

  • You could make a new model and then set its attributes (see question 9709968)
  • A more elegant way is calling the validate method when initializing the model (see question 7923074)

I'm not completely satisfied with these solutions because creating a new instance of the model like described in the backbone documentation shouldn't happen when an error is triggered. Unfortunately, in both solutions you're still stuck with a new instance of the model.

edit: Being stuck with a new instance of the model is actually quite nice. This way you can give the user feedback about why it didn't pass the validator and give the opportunity to correct his/her input.

時窥 2025-01-14 12:03:36

好的。所以,我在这里取得了一些小小的成功。

首先,我编写了自己的验证框架 Backbone.Validator 因为我不喜欢其中任何一个我发现的那些。

其次,我可以通过在创建新模型期间提供的对象中设置silent: false来让验证框架启动验证例程。

除了使用验证框架中的 use_defaults 参数之外,我还可以在初始测试的设置过程中覆盖错误数据。我仍在努力对此进行更多测试,但从 Chrome 浏览器控制台来看似乎一切正常。

OK. So, I'm having some mild success here.

First, I wrote my own validation framework, Backbone.Validator since I didn't like any of the ones out there that I found.

Second, I am able to get the validation framework to set off the validation routine by setting silent: false with in the object provided during the new Model creation.

Along with using the use_defaults parameter from my validation framework I am able to override bad data during setup in initial testing. I'm still working on doing some more tests on this, but it seems to be going OK from from the Chrome browser console.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文