Backbone.js:如何在对象文字中调用集合上的方法

时间:2011-08-14 00:33:21

标签: model-view-controller coding-style backbone.js underscore.js object-literal

我有以下backbone.js代码。我正在使用一个对象文字来组织我的代码,这给我留下了一个关于最佳方法的问题。应用程序(在下面的简化形式中)有一个控制面板(可以显示或隐藏),用于向集合中添加新类别。 (问题如下)

(function($){

    // ============================= NAMESPACE ========================================
var categoryManager = categoryManager || {};

    // ============================= APPLICATION =================================================

categoryManager.app = categoryManager.app || {

    /* Used to Initialise application*/
    init: function(){
        //this.addView = new this.addCategoryView({el: $("#add-new-category")})
        //this.collection = new this.categoryCollection();
        new this.addCategoryView({el: $("#add-new-category")})
        new this.categoryCollection();
    },

    categoryModel:  Backbone.Model.extend({
        name: null
    }),

    addCategoryView: Backbone.View.extend({

        events: {
            "click #add-new-category-button.add" : "showPanel",
            "click #add-new-category-button.cancel" : "hidePanel",
            "click #new-category-save-category" : "addCategory"
        },
        showPanel: function() {
            $('#add-new-category-button').toggleClass('add').toggleClass('cancel');
            $('#add-new-category-panel').slideDown('fast');
        },
        hidePanel: function() {
            $('#add-new-category-button').toggleClass('add').toggleClass('cancel');
            $('#add-new-category-panel').stop().slideUp('fast');
        },
        addCategory: function() {
            //categoryManager.app.collection.create({
            categoryManager.app.categoryCollection.create({ // My Problem is with this line
                name: $('#name').val()
            });
        }
    }),

    categoryCollection: Backbone.Collection.extend({
        model: this.categoryModel,
        initialize: function () {

        }
    })
}
    // ============================= END APPLICATION =============================================

    /* init Backbone */

    categoryManager.app.init();

})(jQuery);

现在显然上面的问题是,调用addCategory函数会尝试在未初始化的对象上调用函数。我通过在init函数中实例化的对象上调用函数而不是来解决问题(参见注释掉的代码)。我的问题是 - 这是正确的做法吗?我发现了一个代码味道。我觉得对象文字的内容不应该依赖于被创建的对象才能有效。除非首先在父对象上调用init函数,否则此实例中的函数addCategory将不起作用。 我应该使用其他模式吗?

如何将“创建新类别表单”的内容传递给集合以便添加(我正在使用create,因为我想自动验证/创建/持久化模型,这似乎是最简单的要做的事)。我是骨干的摇滚新手(这是我的'你好世界')

由于

2 个答案:

答案 0 :(得分:2)

我认为主要问题是你正在将categoryCollection视为一个对象。它不是一个真正的对象,而是一个构造函数。首先,您需要创建一个实例,如您所发现的那样。

然后addCategoryView需要某种方式来引用实例。看起来您没有与视图关联的模型。我建议创建一个模型并将categoryCollection实例存储为模型的属性。这样的事情(警告,未经测试的代码):

var model = new BackBone.Model({
    categories: new categoryManager.app.CategoryCollection()
});

var view = new categoryManager.app.AddCategoryView({
    el: $("#add-new-category"),
    model: model
});

然后您可以在this.model.categories内使用addCategoryView

顺便说一句,一个常见的Javascript约定是大写构造函数的名称。调用构造函数CategoryCollection可能会使代码更清晰。

答案 1 :(得分:0)

您需要在创建模型的新实例

之前初始化集合
addCategory: function() {
    var collection = categoryManager.app.categoryCollection;

    !collection.create && (collection = new collection);
    collection.create({
        name: $('#name').val()
    });
}