javascript - вики - initialize backbone




Backbone.js: вложение представлений через шаблоны (4)

Технически возможно вложить представления, используя шаблоны, что-то вроде этого:

<%= new PhotoCollectionView({model:new PhotoCollection(model.similarPhotos)}).render().el) %>

Я также могу поместить все вещи в метод рендеринга, но шаблоны дают гораздо больше места для гибкости и разметки.

Я попробовал вышеупомянутый вариант, но все, что я получаю в результате на экране, это [HTMLDivElement] .

Если я пытаюсь извлечь из него только HTML-код, используя HTML-код jQuery, я получаю его визуализацию, но оказывается, что распечатываемые DOM-узлы отличаются от тех, на которые ссылаются представления, потому что никакого взаимодействия вообще нет с этими узлами DOM возможно использование экземпляра вида. Например, если в представлении я скажу $(this.el).hide() , ничего не произойдет.

Как правильно, если таковые имеются?


Обычно я сначала отображаю родительский вид. Затем я использую метод this.$('selector') чтобы найти дочерний элемент, который я могу использовать в качестве элемента дочернего представления.

Вот полный пример:

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(); 

Принятый ответ имеет большой недостаток, который заключается в том, что 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;
    }
});

Вам не нужно расширять представление Backbone, если вы этого не хотите, метод renderNested может быть размещен где угодно.

Используя приведенный выше код, вы можете теперь инициализировать ChildView в методе инициализации, а затем просто отобразить его при вызове render ().


Решение инициализировать новый объект каждый раз, когда вы визуализируете, кажется мне очень неэффективным. Особенно это:

render: function() {
    var child_view = new ChildView({ el: this.$('#child-el') }); //This refers to ParentView. 
    return this;
  }

В идеале рендеринг родителя должен быть что-то вроде

render: function() {
   this.$el.html(this.template());
   this.childView1.render();
   this.childView2.render();
}

И создание потомков должно происходить только при инициализации родителя:

initialize: function() {
       this.childView1 = new ChildView1(selector1);
       this.childView2 = new ChildView2(selector2);
} 

проблема в том, что у нас нет selector1 и selector2 до рендеринга родительского шаблона. Это где я застрял прямо сейчас :)


Я не знаю о самом шаблоне, но я делал это раньше с помощью таблиц и списков. Во внешнем шаблоне просто заглушка:

<script type="text/template" id="table-template">
    <table>
        <thead>
            <th>Column 1</th>
        </thead>
        <tbody>
        </tbody>
    </table>
</script>

и для отдельных элементов: <% = field1%>

затем в вашем методе рендеринга просто визуализируйте отдельные элементы и добавьте их к элементу tbody ...







templating