Backbone.js:通过模板嵌套视图

use*_*232 18 javascript jquery templating backbone.js

在技​​术上是否可以使用模板嵌套视图,类似于:

<%= new PhotoCollectionView({model:new PhotoCollection(model.similarPhotos)}).render().el) %>
Run Code Online (Sandbox Code Playgroud)

我也可以将所有内容都放在渲染方法中,但模板为灵活性和布局提供了更多空间.

我尝试了前面提到的变体,但我在屏幕上得到的结果是[HTMLDivElement].

如果我尝试只提取HTML,使用jQuery的HTML,我会将其渲染,但事实证明,打印出来的DOM节点与视图引用的DOM节点不同,因为没有任何交互使用视图实例可以使用这些DOM节点.例如,如果在视图中我说$(this.el).hide(),什么都不会发生.

什么是正确的方法,如果有的话?

Sky*_*son 29

我通常首先渲染父视图.然后我使用该this.$('selector')方法查找可以用作子视图的el的子元素.

这是一个完整的例子:

var ChildView = Backbone.View.extend({
  //..
})

var ParentView = Backbone.View.extend({
  template: _.template($('#parent-template').html()),
  initialize: function() {
    _.bindAll(this, 'render');
  }
  render: function() {
    var child_view = new ChildView({ el: this.$('#child-el') }); //This refers to ParentView. 
    return this;
  }
});

var v = new ParentView();
v.render(); 
Run Code Online (Sandbox Code Playgroud)

  • 这似乎有点低效.每次呈现父级时,您都在重新初始化子视图. (6认同)
  • 同意亚历山德罗.除了效率低下之外,每次呈现父视图时,您还会在子视图中松散动态状态.查看[Backbone.Subviews](https://github.com/rotundasoftware/backbone.subviews)以获得随时可用的极简主义解决方案 (5认同)
  • 您应该在初始化中创建子视图,并将其存储为父视图的属性.然后在父级渲染函数内的子视图上调用render. (2认同)

Ale*_*one 14

接受的答案有一个重大缺陷,即每次渲染时都会重新初始化ChildView.这意味着您将丢失状态,并且可能必须在每个渲染上重新初始化复杂视图.

我在这里写了一篇博客:http://codehustler.org/blog/rendering-nested-views-backbone-js/

总而言之,我建议使用这样的东西:

var BaseView = Backbone.View.extend({

    // Other code here...

    renderNested: function( view, selector ) {
        var $element = ( selector instanceof $ ) ? selector : this.$el.find( selector );
        view.setElement( $element ).render();
    }
});

var CustomView = BaseView.extend({

    // Other code here...

    render: function() {
        this.$el.html( this.template() );
        this.renderNested( this.nestedView, ".selector" );
        return this;
    }
});
Run Code Online (Sandbox Code Playgroud)

如果您不想扩展Backbone视图,则可以将renderNested方法放在任何您喜欢的位置.

使用上面的代码,您现在可以在初始化方法中初始化ChildView,然后在调用render()时简单地渲染它.