Дополнительные обертки div Backbone Marionette: решение tagName в других потоках не работает для ДИНАМИЧЕСКИХ вкладок

Ниже приведен фрагмент примера элемента управления вкладками отсюда: http://layout.jquery-dev.net/demos/tabs.html

Эти вкладки внутри этих разделителей — именно то, что мне нужно. Но мне нужно, чтобы вкладки динамически добавлялись и удалялись в зависимости от взаимодействия с пользователем. Думал, что смогу сделать это с составными представлениями или представлениями коллекции в основной марионетке - добавлять/удалять элементы из базовой коллекции, а вкладки появляются и исчезают в пользовательском интерфейсе.

Концептуально это не должно быть сложно. Но трудность возникает из-за ужасной проблемы с дополнительной оберткой div, которая так обсуждается в различных темах на протяжении многих лет.

Дополнительные элементы div в представлениях элементов и макетах в Backbone.Marionette

В моем случае каждый li в моем ul появляется в своем собственном div. Это портит CSS в приведенном ниже фрагменте кода. Это ломает некоторые из них, поэтому все выглядит странно. Если бы я мог просто вывести вывод ниже, все не выглядело бы странно.

    <ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all ui-sortable" role="tablist">
            <li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0" aria-controls="tabs-west-1" aria-labelledby="ui-id-1" aria-selected="true">
                <a href="#tabs-west-1" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-1">Nunc tincidunt</a>
            </li>
            <li class="ui-state-default ui-corner-top" role="tab" tabindex="-1" aria-controls="tabs-west-2" aria-labelledby="ui-id-2" aria-selected="false">
                <a href="#tabs-west-2" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-2">Proin dolor</a>
            </li>
    </ul>

В приведенном выше выводе сложные li отображаются непосредственно в контейнере ul, который также является сложным. Почему я не могу сделать этот вывод?

Этот дополнительный обертывающий div, по-видимому, является поведением марионетки по умолчанию при рендеринге itemView. Многие ответы в этих темах сосредоточены на установке для свойства tagName значения li. Проблема в том, что это создает пустой общий li. Посмотрите на ли во фрагменте выше. У них много свойств.

Мои li должны иметь уникальные идентификаторы, стили и другие атрибуты, подобные приведенным выше. Преобразование tagName вашего представления элемента в li просто создает простой li в вашем выводе. Как мне получить свои динамические идентификаторы, классы стилей и тому подобное?

Моей первой попыткой исправить это было вставить код li в мой шаблон handlebars, чтобы я мог закодировать его с помощью необходимых мне динамических данных:

    var TabItemView = Marionette.ItemView.extend({
        template: Handlebars.compile(
            '<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0" aria-controls="tabs-{{id}}" aria-labelledby="ui-id-{{id}}" aria-selected="true">' +
                '<a href="#tabs-{{id}}" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-{{id}}">{{tabName}}</a>' +
             '</li>'
        ),
    });

Но теперь каждый li в моем списке помещается в собственный контейнер div. Каждая комбинация использования переопределения el, tagName, appendHtml приводит либо к элементу-обертке, либо к неверным результатам - например, переопределение appendHtml заставляет каждую новую вкладку просто заменять существующие вкладки - поэтому у меня когда-либо была только одна вкладка, последняя добавленная.

Что мне здесь не хватает? Почему я не могу определить шаблон для li, содержащего в нем динамические данные, и отобразить его НЕПОСРЕДСТВЕННО в мой ul БЕЗ дополнительного оборачивающего div вокруг каждого элемента списка? Я предполагаю, что другой способ сформулировать вопрос: я работаю с существующим шаблоном, который ТРЕБУЕТ сложные li. Как мне создать их в составном виде или в виде коллекции БЕЗ дополнительного контейнера-обертки вокруг них?

Backbone и Marionette, кажется, обещают делать подобные вещи более управляемым способом, чем делать это в простом jQuery. У меня нет такого опыта. Что я не вижу?


person Robert    schedule 09.10.2013    source источник


Ответы (2)


Я не использую Marionette, но не понимаю, почему она переопределяет поведение Backbone по умолчанию. Это должно дать вам представление:

var TabView = Marionette.ItemView.extend({
    tagName: 'ul',
    className: 'ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all ui-sortable" role="tablist',
    render: function() {
         //something like this
         var _this = this;
         this.collection.each(function(item){
             var view = new TabItemView({
                 model: item
             });
             _this.$el.append(view.render().el)
         })
     }
});

var TabItemView = Marionette.ItemView.extend({
    tagName: 'li',
    className: 'ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tablist',
    template: Handlebars.compile(
        '<a href="#tabs-{{id}}" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-{{id}}">{{tabName}}</a>'
    ),
});
person TYRONEMICHAEL    schedule 09.10.2013

Что касается управления представлениями и данными для создания определенного вывода HTML, я предлагаю вам взглянуть на мой пост в блоге здесь: http://davidsulc.com/blog/2013/02/03/tutorial-nested-views-using-backbone-marionettes-compositeview/

Это должно заставить вас структурировать представления, чтобы они правильно отображались. Затем вы можете добавить http://backbonejs.org/#View-attributes в смесь, чтобы получить ваши сложные атрибуты (для которых нет существующих атрибутов Backbone, таких как className).

person David Sulc    schedule 09.10.2013