Backbone - 验证不在创建,只更新/编辑?

时间:2012-02-20 01:34:22

标签: javascript asp.net-mvc-3 backbone.js

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

//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 () {

        }
    });
})

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

2 个答案:

答案 0 :(得分:4)

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

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

  • 您可以制作新模型,然后设置其属性(请参阅question 9709968
  • 更优雅的方法是在初始化模型时调用validate方法(请参阅question 7923074

我对这些解决方案并不完全满意,因为在触发错误时不应该创建骨干documentation中描述的模型的新实例。不幸的是,在这两种解决方案中,你仍然坚持使用该模型的新实例。

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

答案 1 :(得分:2)

行。所以,我在这里取得了一些成功。

首先,我编写了自己的验证框架Backbone.Validator,因为我不喜欢我找到的任何一个。

其次,通过在silent: false创建期间提供的对象中设置new Model,我可以获得验证框架以启动验证例程。

除了使用验证框架中的use_defaults参数外,我还能够在初始测试中设置时覆盖错误数据。我还在努力对此进行更多测试,但是从Chrome浏览器控制台看起来似乎没问题。