【问题标题】:advice on how to design an extendable backbone view关于如何设计可扩展主干视图的建议
【发布时间】:2013-03-20 01:38:44
【问题描述】:

我有以下主干应用程序。

这是一个通用的 crud 视图,具有以下模板:

<div id="<%= crudId %>">
  <div class="header-view"></div>
  <div class="table-view"></div>
  <div class="form-view"></div>
</div>

你可以在这里看到 crud:http://bbbootstrap.com.ar/index.html#Wine

视图本身有子视图,要在表格视图和表单视图中呈现。

问题是我希望它是一个基本的 crud 视图,并且易于接受,添加新的子视图,例如,添加一个新面板来发出一些批量操作。

这些是我目前提出的可能的解决方案

1- 继承:创建一个新的 CrudBulkView 继承自 CrudView,修改模板以具有批量视图占位符。

pro:继承可以提供相当优雅和简单的解决方案 缺点:它有点限制,我希望能够编写 BulkView 并将其添加到 CrudView。

2- 向 crudview 添加一个方法,例如 addView(view, place),其中 place 类似于 'beforeForm'、'afterForm'、'beforeTable' 等......(它的代码太硬了......

缺点:编码太硬

3- 在 CrudView 渲染容器之后,为我要添加的每个子视图传递一个函数,该函数负责创建 dom 并附加到它。该方法可以调用 setEl 并返回新创建的 el。

专业人士:非常灵活 缺点:将子视图附加到 dom 的过程增加了一些复杂性

4-修改 crudView 模板,然后附加到它,如下所示:

<div id="<%= crudId %>">
  <div class="header-view"></div>
  <div class="table-view"></div>
  <div class="form-view"></div>
  <div class="bulk-view"></div
</div>

然后 bulkView.el 将是 '.bulk-view'

pro:简单的方法 缺点:必须处理字符串,而不是处理 dom

我认为我想要达到的目标并不奇怪。我只想在容器视图中添加一个视图,尽可能地解耦,并且能够确定它应该在哪里呈现。

【问题讨论】:

    标签: backbone.js backbone-views


    【解决方案1】:

    在阅读了您对我之前的回答的回复后,我浏览并修改了我的示例,希望能让您了解如何使用命名视图来实现系统,让您可以根据需要控制排序。如果这有帮助,或者您对它的工作原理有任何疑问,请告诉我。

    var viewCtor = Backbone.View.prototype.constructor;
    
    // Assuming we have a reference to the subviews already
    var BaseCrudView = Backbone.View.extend({
      // This is null for an important reason, see comment in constructor
      subViews: null,
    
      // Override the constructor instead of initialize since this is meant to be a base object, so things that
      // inherit don't have to remember to call the parent inialize every time.
      constructor: function() {
        viewCtor.apply(this, arguments);
    
        // It is important this is initialized when instantiating the view rather than in the prototype.
        // Backbone's extend() will "copy" the prototype properties of the parent when extending, which really
        // just performs an assignment. If this were initialized above in the prototype then all children
        // that inherit from that prototype would share the exact same instance of the array/object. If a child
        // adds something to the array, it would be changed for all instances that inherit from the parent.
        this.subViews = {
          header: new HeaderView(),
          table: new TableView
        };
    
        this.subViewOrder = [
          'header',
          'table'
        ];
      },
    
      addBefore: function(subView, name, beforeView) {
        this.subViews[name] = subView;
        var viewLoc = this.subViewOrder.indexOf(beforeView);
        if(viewLoc == -1) {
          viewLoc = 0;
        }
        this.subViewOrder.splice(viewLoc, 0, name);
      },
    
      addAfter: function(subView, name, afterView) {
        this.subViews[name] = subView;
        var viewLoc = this.subViewOrder.indexOf(afterView);
        if(viewLoc == -1) {
          viewLoc = this.subViewOrder.length - 1;
        }
        this.subViewOrder.splice(viewLoc + 1, 0, name);
      },
    
      moveBefore: function(name, beforeView) {
        this.addBefore(this.subViews[name], name, this.subViewOrder.splice(this.subViewOrder.indexOf(name), 1));
      },
    
      moveAfter: function(name, afterView) {
        this.addAfter(this.subViews[name], name, this.subViewOrder.splice(this.subViewOrder.indexOf(name), 1));
      },
    
      render: function() {
        var that = this;
    
        _.each(this.subViewOrder, function(viewName) {
          // Assumes the render() call on any given view returns 'this' to get 'el'
          that.$el.append(this.subViews[viewName].render().el);
        });
    
        return this;
      }
    });
    
    var BulkCrudView = BaseCrudView.extend({
      inialize: function() {
        // Skipping the last parameter causes it to insert at the end
        this.addAfter(new BulkView(), 'bulkView');
      }
    });
    

    有了这个,您可以轻松地扩展 BulkCrudView 并在初始化时修改其 subViews 数组以添加/插入您想要的任何内容。不过,它也可以实例化 BaseCrudView 并使用视图方法。任何感觉更清洁和/或让您的船漂浮的东西。

    【讨论】:

    • 感谢您的回复。在我给出的示例中,我只是一个接一个地附加每个子视图。但我希望它更灵活。假设我想在标题上方添加一个子视图,或者在标题之后和表体之前,或者在末尾等......我需要某种模板来指定我希望每个子视图插入的位置。
    • 您可以使用一个带有命名键的对象来引用视图,然后是一个指定顺序的数组,您可以在从它继承的每个视图中根据需要对其进行修改。这会实现更多您正在寻找的东西吗?我可以修改我的答案以证明这是否有帮助。
    • 我刚刚修改了我的答案,让我知道你的想法。
    猜你喜欢
    • 2014-01-16
    • 2016-06-16
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多