【问题标题】:Backbone.js: How to call methods on the collection within an object literalBackbone.js:如何在对象文字中调用集合上的方法
【发布时间】:2011-08-14 00:33:21
【问题描述】:

我有以下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 函数中实例化的对象上调用函数 instead 来解决问题(参见注释掉的代码)。我的问题是 - 这是正确的做法吗?我检测到代码气味。我觉得对象文字的内容不应该依赖于正在创建的对象才能有效。除非先在父级上调用了 init 函数,否则此实例中的函数 addCategory 将不起作用。 这里还有其他我应该使用的模式吗?

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

谢谢

【问题讨论】:

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


    【解决方案1】:

    我认为主要问题是您将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
    });
    

    那么你可以在addCategoryView内部使用this.model.categories

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

    【讨论】:

    • 我的理解是集合包含模型而不是逆模型。模型包含一个本身包含模型的集合(就像我的集合一样)是否可以(不是“将工作”中的“可以”,但“正确的事情”中的可以)?感谢您的意见。
    • 我认为这没问题,并且有助于封装 - MVC 类型架构的一般概念是模型包含视图需要呈现自身的所有数据。
    • 谢谢 - 你会看到我已经为此付出了很多,所以我会保持开放,看看我是否能得到更多的答案。我无法让您的代码工作(第一行),所以我这样做了。 AddViewModel: Backbone.Model.extend({ initialize: function(){ this.categories = new categoryManager.app.CategoryCollection; }, categories: null })。如果我省略初始化函数,它会失败 - 我不能直接将构造函数分配给“类别”属性。
    • 示例代码不太正确 - 希望现在更好
    • 不 - 如果我尝试直接初始化集合,我会收到以下错误。 'categoryManager.app 未定义'。如果我在模型的初始化方法中初始化集合,那么它会按预期工作。
    【解决方案2】:

    您需要在创建模型的新实例之前初始化集合

    addCategory: function() {
        var collection = categoryManager.app.categoryCollection;
    
        !collection.create && (collection = new collection);
        collection.create({
            name: $('#name').val()
        });
    }
    

    【讨论】:

    • 嗨。我已经知道了(请参阅我的代码中已注释掉的行)。您的示例中第三行代码的目的是什么?
    • !collection.create 检查collection 是否未初始化,如果未初始化,则初始化集合并将其分配给collection 变量
    • !collection.create && (collection = new collection); 等于 if(!collection.create) { collection = new collection }
    猜你喜欢
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 2012-08-06
    相关资源
    最近更新 更多