如何组织骨干多应用程序?

时间:2013-06-07 21:01:50

标签: javascript backbone.js dry organization

我使用没有包装器或框架的干净骨干。

所以我创建了一个由某些产品管理的网站。我有两个动态页面:

  • add.php
  • edit.php

这些页面是独立的骨干应用程序。

在这两个页面中,都有一个元素显示产品类别。通常它是一个下拉列表。

接下来,我将描述我的脚本的近似结构。这很简单。

js
+- models
|  +- Category.js
|  ...
+- collections
|  +- Categories.js
|  ...
+- views
|  +- CategoriesView.js
|  ...

CategoryView.js 包含:

App.Views.CategoriesViews = Backbone.View.extend({
    template: _.template($('#tpl-categories').html()),

    events: {
        'change select': 'toggle'
    },

    initialize: function () {
        _.bindAll(this, 'render');

        this.collection.on('reset', this.render);
    },

    render: function () {
        this.$el
            .html(this.template({ collection: this.collection.toJSON() }));

        return this;
    },

    toggle: function () {
        // Some actions here
        var catId = this.$el.children('select').val();
        App.trigger('toggleCategories', catId);
    }

});
视图的

初始化如下所示:

new App.Views.CategoriesViews({
   el: $('#select-box-cats'),
   collection: new App.Collections.Categories
});

由于这个元素位于两个页面上(add.php和edit.php),因此它适用于这两个页面。

我们假设模板的名称可以在两个页面上设置相同:

<script type="text/template" id="tpl-categories">

虽然我认为这不是一个好习惯。

好吧,最后我的问题。

如果其中一个页面需要向视图添加事件处理程序,会发生什么。例如:

initialize: function () {
    _.bindAll(this, 'render', 'action');

   this.collection.on('reset', this.render);
   this.collection.on('request', this.action);
},

我在request集合中添加了一个事件。但是,此事件不应出现在其他页面上。

怎么办?要创建一个单独的视图文件,以改变页面的需求?但它违反了DRY的原则并产生了很多客户端代码!

2 个答案:

答案 0 :(得分:1)

您可以在创建视图时将选项传递给视图。

在您的编辑页面上:

new App.Views.CategoriesViews({
    el: $('#select-box-cats'),
    collection: new App.Collections.Categories,
    bindRequest: true, // Trigger the request event.
    toggleCategories: true // Toggle the categories in the toggle method.
});

在您的添加页面上:

new App.Views.CategoriesViews({
    el: $('#select-box-cats'),
    collection: new App.Collections.Categories,
    bindRequest: false, // Do not trigger the request event.
    toggleCategories: false // Do not toggle categories in the toggle method.
});

在你看来:

initialize: function() {
    _.bindAll(this, 'render', 'action');

    this.collection.on('reset', this.render);

    // this.options is automatically populated with any parameters included 
    // upon creation.
    if (this.options.bindRequest) {
        this.collection.on('request', this.action);
    }
},

toggle: function () {
    // Some actions here
    var catId = this.$el.children('select').val();

    // Options are available from any method in the view.
    if (this.options.toggleCategories) {
        App.trigger('toggleCategories', catId);
    }
}

答案 1 :(得分:0)

我觉得视图不应该有任何特定于集合的逻辑。它唯一应该做的是根据触发的事件渲染视图。

所以我在这种情况下要做的是bind SubView上的公共事件

initialize: function () {
    _.bindAll(this, 'render', 'action');

   this.collection.on('reset', this.render);
},

这两个页​​面都很常见。

在视图实际在其父视图中实例化之前..

AddView

initialize : function() {
    this.collection = new App.Collections.Categories
    this.collection.on('request', this.action);
},
new App.Views.CategoriesViews({
   el: $('#select-box-cats'),
   collection: this.collection
});