Backbone:用于以正确顺序呈现和重新呈现订阅者视图的模式

时间:2012-05-02 22:41:57

标签: oop backbone.js backbone-events

所以基本上我一直在玩这种pubsub模式,当父级“控制器”视图调用时子视图重新呈现(对不起,如果那令人困惑)。如果子视图基于对集合或模型的获取(下面未显示),有时它们也不会以正确的顺序呈现我也需要它们,即如果SubView1是Subview2的小导航,我不想要它在SubView2下面。

我认为必须存在这种常见问题的模式。 Lemme知道这是否有意义,我会澄清。但我正在处理的基本情况如下。

标记:

 <div id="main-container">
   <div class="inner-container"></div>
 </div>

JS:

 var ToggleNavView = Backbone.View.extend({
    //let's say this template has two links
    template: Handbars.compile(linkstmpl),

    el: $('#main-container'),
    events: {
      "click a": "toggleViews"
    }
    initialize: function(){
      _.bindAll(this, 'render', 'toggleViews');

      // whoa, nice looking event aggregator http://bit.ly/p3nTe6
      this.vent = _.extend({}, Backbone.Events);

      this.render();
    },
    render: function(){
       $(this.el).append(this.tmpl);

       // suppose subviews below are declared as modules above with, say, requirejs
       var sub1 = new SubView1({ vent: this.vent }),
           sub2 = new SubView2({ vent: this.vent });


    },

    toggleViews: function(e){
      e.preventDefault();

      // get name of section or view you're toggling to
      var section = $(e.currentTarget).data('section');

      // publish events to subscribers
      this.vent.trigger('toggleInboxViews', this, section);


    },

   });

   var SubView1 = Backbone.View.Extend({
      template: Handlebars.compile(tmpl1),
      initialize: function(ops){
        _.bindAll(this, 'render', 'removeOrRerender');

        this.vent = ops.vent || null;
        this.render()
      },
      render: function(){
        $(this.el).append(this.template()).appendTo($(".inner-container"))
      },

      removeOrRerender: function(obj, section){
        if( section == 'my-section'){
          this.render();
        } else if( section == 'other-section' ) {
          $(this.el).fadeOut();
        }
      },

    })

    // another subview with same functionality etc... 

    // init view
    new ToggleNavView();

1 个答案:

答案 0 :(得分:1)

如果您需要子视图显示在特定位置,那么父视图应该定义该结构,并且应该告知子视图在哪里呈现自己。然后,由于整体结构不会改变,因此绘制的内容顺序无关紧要。

例如,如果您希望一个子视图显示在顶部而另一个子视图显示在它下面,则主视图应如下所示:

<div id="main-view">
    <div id="sub1"></div>
    <div id="sub2"></div>
</div>

然后主视图将使用以下内容呈现子视图:

 var sub1 = new SubView1({ el: this.$el.find('#sub1'), vent: this.vent }),
 var sub2 = new SubView2({ el: this.$el.find('#sub2'), vent: this.vent });

通过为子视图指定el,它们在页面上的位置不再是他们的问题,如果它们以不同的顺序呈现,它们将不会移位。这种结构的一个令人愉快的副作用是,子视图只关注自己,并且很好地自成一​​体;父视图只需要通过正确构造模板将所有部分放在正确的位置,一切正常。

这是一个简单的演示,可能会澄清结构:http://jsfiddle.net/ambiguous/9u3S5/