【问题标题】:backbone template nested in another template嵌套在另一个模板中的主干模板
【发布时间】:2012-05-26 10:46:54
【问题描述】:

是否可以将模板嵌套在模板中并通过主干视图访问?

例如,我有 View1 使用 Template1,而 View2 使用 Template2。 Template2 实际上需要在 Template1 内的一个 DIV 中。我将模板 2 的 DIV 容器放在具有适当 ID 的模板 1 中,但在呈现页面时它不显示。如果我从 Template1 中删除 Template2 div 容器并将其放入页面正文中,它就可以正常工作。

所以只是想知道这是否可能,或者我是否必须嵌套视图/模型等才能完成这项工作?

Template2 中的数据在技术上与 Template1 无关,只是需要显示在嵌入 Template1 的页面上的某个位置。

【问题讨论】:

  • 你能分享一些代码吗?
  • 我知道这不能回答你的问题,但 Ember js 支持的东西接近。您可以定义嵌套资源...哪种分类允许您在模板中嵌套模板。 emberjs.com/guides/routing/defining-your-routes

标签: javascript jquery templates backbone.js underscore.js


【解决方案1】:

我过去处理这个的方式是分别定义两个视图,然后在渲染View1的时候,新建一个View2,渲染,插入到View1中。所以:

window.View1 = Backbone.View.extend({
    render: function() {
        this.view2 = new View2();
        this.$('insert-view-here').append(this.view2.render().el);
    }
});

【讨论】:

  • 这种情况下如何处理内部元素的变化呢?你总是从上到下渲染内部元素是否会以某种方式改变自己?
  • 内部元素的更改可以由第二个视图处理,就像您在任何其他情况下处理它们一样。如果由于某种原因,父视图或模型发生更改并需要重新渲染 html,则将在此渲染方法中重新创建子视图。
【解决方案2】:

您应该为此创建子视图。

我喜欢在关闭时私有化子视图并返回公共视图。

var View = (function (BV) {
    var View, Subview;

    // Only this main view knows of this subview
    Subview = BV.extend({ 
        template: _.template( subtmpl ),

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

    View = BV.extend({
        template: _.template( tmpl ),

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

            var subview = new SubView({ model: this.model }); 

            // replace a div in your template meant for teh subview with the real subview
            this.$el.find( "#subview" ).replaceWith( subview.render().el );

            return this;
        }   
    }); 

    return View;

}(Backbone.View));

var view = new View({ model: user });
var subview = new Subview; // Reference Error

【讨论】:

    【解决方案3】:

    当您需要在 Template1 中多次包含 Template2(如 <ul> 中的 <li> 元素)时,另一个有用的选项是将 Template2 函数传递给 Template1。 (来自Rico Sta Cruz' Backbone Patterns。)

    TasksList = Backbone.View.extend({
      // Template1, inlined in js.
      template: _.template([
        "<ul class='task_list'>",
          "<% items.each(function(item) { %>",
            "<%= itemTemplate(item) %>",
          "<% }); %>",
        "</ul>"
      ].join('')),
    
      // Template2, inlined in js.
      itemTemplate: _.template(
        "<li><%= name %></li>"
      ),
    
      render: function() {
        var html = this.template({
          items: tasks /* a collection */,
          itemTemplate: this.itemTemplate
        });
    
        $(this.el).append(html);
      }
    });
    

    【讨论】:

      【解决方案4】:

      据我了解,典型的方式是将视图视为可以相互嵌入的完整对象。假设您有两个视图,ViewA 和 ViewB。以下代码显示了如何将 ViewB 附加到 ViewA 中。

      # this is coffeescript, but it's easily translated to JS
      class ViewA extends Backbone.View
          initialize: () ->
              this.render()
      
          render: ()->
              this.$el.append(new ViewB().$el)
              this.$el.append(new ViewB().$el)
              return this
      

      您可以了解 ViewB 的管理方式(将其分配给属性或其他),或者将不同的构造函数参数传递给每个 ViewB 实例。

      【讨论】:

        【解决方案5】:

        不需要 jQuery append() 或涉及双 jQuery 范围的附加 SubView 对象的更精简的解决方案是严格使用下划线方法进行预渲染/预编译,并将子视图作为字符串插入,使用内部主模板中的注释标签。

        View = Backbone.View.extend({
          template: _.template(...),
          prerender: function(tpl,model){// pre-render a component
              var template = _.template(tpl);
              return template(model);
          },
          render: function(){
            var model = { ... };
            var component = this.prerender(this.itemTemplate, model);
            this.$el.html(this.template(model).replace('<!--#component-->', component));
          }
        });
        

        如果您的模板不是常量并且依赖于当前作用域的属性,它尤其有用。

        请注意,对于这个问题的范围,您必须将 View2 模型传递给组件。

        【讨论】:

          猜你喜欢
          • 2012-01-23
          • 1970-01-01
          • 2011-09-08
          • 1970-01-01
          • 2020-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多