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

发布于 2024-11-29 11:20:34 字数 2375 浏览 1 评论 0原文

我有以下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 因为我想要自动验证/创建/保留模型,这似乎是最简单的事情)。我是一个有骨气的底层新手(这是我的“你好世界”)

谢谢

I have the following backbone.js code. I'm using an object literal for organizing my code, which has left me with a question regarding the best way to proceed. The application (in its simplified form below) has a control panel (which can be shown or hidden) which is used to add new categories to a collection. (Question follows)

(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);

Now obviously the problem with the above, is that calling the addCategory function tries to call a function on an object which is uninitialized. I've worked round the problem (see commented out code) by calling the function instead on a object which is instantiated within the init function. My question is - is this the right thing to do? I detect a code smell. I feel that the contents of the object literal shouldn't rely on the object being created in order to be valid. the function addCategory in this instance wouldn't work unless the init function had been called on the parent first. Is there another pattern here that I should be using?

How else would I pass the contents of the 'create new category form' to the collection in order to be added (I'm using create because I want to automatically validate/create/persist the model and It seems like the easiest thing to do). I'm a rock bottom novice with backbone (this is my 'hello world')

Thanks

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

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

发布评论

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

评论(2

小忆控 2024-12-06 11:20:34

我认为主要问题是您将 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 可能会使代码更清晰一些。

I think the main issue is you are treating categoryCollection as if it's an object. It's not really an object, but a constructor function. So first you need to create an instance, as you have discovered.

Then the addCategoryView needs some way of referencing the instance. It looks like you don't have a model associated with the view. I would suggest creating a model and storing the categoryCollection instance as a property of the model. Something like this (warning, untested code):

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

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

Then you can just use this.model.categories from inside addCategoryView.

As an aside, a common Javascript convention is to capitalize the names of constructors. Calling the constructor CategoryCollection might make the code a little bit clearer.

小姐丶请自重 2024-12-06 11:20:34

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

addCategory: function() {
    var collection = categoryManager.app.categoryCollection;

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

You need to initialize collection before create a new instance of a model

addCategory: function() {
    var collection = categoryManager.app.categoryCollection;

    !collection.create && (collection = new collection);
    collection.create({
        name: $('#name').val()
    });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文