1

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

所以我创建了一个网站来管理一些产品。为此,我有两个动态页面:

  • 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 的原则,并且产生了大量的客户端代码!

4

2 回答 2

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);
    }
}
于 2013-06-07T21:06:51.443 回答
0

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

所以在这种情况下我要做的是bindSubView 上的常见事件

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

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

这两个页面都很常见。

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

添加视图

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
});
于 2013-06-07T21:16:56.600 回答