Подтвердить что ты не робот

Рендеринг макетов с помощью Backbone.js

Если вы должны были создать одностраничное веб-приложение (SPWA) с помощью Backbone.js и jQuery с - например, двумя контроллерами, для каждой из которых требовались уникальные макеты страниц, как бы вы отображали макет?

  • ControllerA - это расположение трех столбцов.
  • ControllerB - это расположение двух столбцов.
  • Маршрут по умолчанию активирует ControllerA.Welcome() - первоначальный рендеринг.
  • Оба контроллера имеют разные представления, отображаемые в своих столбцах, которые используют преимущества модели Backbone.js/view goodness.

Проблема

Когда пользователь запрашивает маршрут, сопоставленный с ControllerB, весь макет страницы должен измениться, чтобы больше не использовать макет ControllerA. Это скроет макет ControllerA и покажет макет ControllerB - или, отринув макет, если он еще не был в DOM.

Моя первая мысль

Можно ли использовать представление Backbone.js для рендеринга макета, а затем визуализировать каждый столбец с его представлениями, связанными с моделью?

Моя вторая мысль

Не могли бы вы добавить метод настройки/макета к контроллеру, который использовал jQuery для визуализации макета, а затем разрешить действие, ответственное за маршрут, сделать это? Использование jQuery внутри контроллера немного для меня немного, но я хочу, чтобы контроллер отвечал за то, чтобы для него были видны правильные макеты.

Вот фрагмент моей второй мысли:

var Controller = Backbone.Controller.extend
({
    routes :
    {
       "" : "welcome" // default action
    }
    /** Constructor **/
    ,initialize: function(options)
    {
        console.log('Workspace initialized');               
    }
    // LAYOUT
    ,renderLayout : function ()
    {
        console.log('Rendering Layout.');
        var $ = window.$;
        var layout = require('js/layout/app/big_menu');
        $(layout.parent).html(layout.html);
    }
    // ACTIONS
    /** Default Action **/
    ,welcome : function ()
    {
        this.renderLayout();
        console.log('Do the whole model/view thing...');
    }
});

Спасибо

Спасибо, что нашли время ответить. Я ценю это!

4b9b3361

Ответ 1

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

Это хорошо работает, когда у вас есть один макет, все становится веселее, когда у вас много. Вы можете поместить все макеты на страницу и скрыть различные конфигурации в зависимости от вашей логики. Вы можете видеть, что макет является исходным видом иерархии. Таким образом, вы создаете макет, а затем загружаете представления.

Нет никакого реального способа сделать это. Для каждого есть плюсы и минусы. Одна вещь, которую я бы не сделал, - это сделать макет в контроллере. Я помещаю весь рендеринг и html в представления, чтобы я мог разбираться с логикой на контроллере и модели (думаю, здесь MVC).

Ответ 2

Я склонен соглашаться с Жюльеном - приятно держать ваши макеты как апатриды, насколько это возможно. Все всегда выложено на странице, в форме скелета, по крайней мере. Когда вам нужно отобразить конкретный макет или конфигурацию, вы лениво визуализируете его содержимое и отображаете эту часть пользовательского интерфейса с помощью CSS. Для этого полезны взаимоисключающие CSS-классы: "проекты-открытые", "открытые документы", "заметки-открытые".

Ответ 3

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

  • Создайте appController, контроллер singleton для приложения.
  • AppController создает mainView, это представление, ответственное за рендеринг скелета страницы и обработку кликов для постоянных элементов на странице (кнопки входа/выхода из системы и т.д.).
  • mainView создает несколько дочерних элементов для разных частей страницы, навигации, сухарей, заголовка, панели инструментов, contentContainer и т.д. Это инструменты приложения, и они не меняются, хотя их соответствующий контент делает. ContentArea, в частности, может содержать любой макет.
  • AppController запускается через зарегистрированные модули, инициируя mainModuleController для каждого из них. Все они имеют схемы маршрутизации пространств имен.
  • Backbone.history.start()

МодульКонтроллеры все получают доступ к appController при инициализации. Когда вы ловите хэш-местоположение, они отправляют событие pageChange в appController, содержащий объект pageManifest. Объект pageManifest содержит всю информацию, необходимую для установки соответствующих представлений, таких как информация о панировке, информация заголовка и, самое главное, ссылка на экземпляр contentView. AppController использует информацию в pageManifest для настройки разных постоянных представлений, удаляет прежний контентный контент в контенте contentContainer и вставляет содержимое содержимого, представленное модулем, в контейнер.

Таким образом, разные дизайнеры могут работать на разных модулях, и все, что им нужно знать, это спецификация объекта pageManifest и то, как должен выглядеть контент. Они могут самостоятельно создавать сложные системы маршрутизации, использовать свои собственные модели и настраиваемые contentViews (хотя мы планируем наследовать библиотеку listViews, objectViews и т.д.).

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

Ответ 4

У меня есть одна и та же проблема независимо от Backbone или любой другой js framework/library.

Представьте, что у вас есть представление SIGN IN FORM, для которого требуется один макет столбца, и вы вводите представление в один единственный div.

Затем, после успешного входа в систему, каким-то образом визуализируется другой макет (скажем, зона HEADER, зона FOOTER, зона LEFT, а затем зона MAIN (правый столбец) для всего остального.

Заголовок может содержать вид LOGO (если он имеет функциональность) и представление GLOBAL/USER MENU. Зона LEFT будет содержать представление PRIMARY NAV.

Тогда дальнейшая сложность; Каждая ссылка в представлении PRIMARY NAV загружает новый макет, готовый для дальнейшего просмотра, чтобы внедрить себя.

Я не хочу, чтобы обычные контроллеры/представления заботились о том, какой макет в настоящее время отображается, только что их контейнерный элемент существует и готов к вводу.

Я думал об использовании маршрутов (не в традиционном смысле) умным способом:

function LayoutController() {
App.addRouteMatcher("/sign_in/*", this.renderSignInLayout); // single column
App.addRouteMatcher("regex to represent anything but sign_in", this.renderMainLayout); // header, footer, primary nav, main zone
App.addRouteMatcher("/section1/*", this.renderSubLayoutForSection1); // puts a 1 column layout in the main zone
App.addRouteMatcher("/section2/*", this.renderSubLayoutForSection2); // puts a 2 column layout in the main zone 
}

Считаем, что если маршрут был "/section1/whatever/sub/page/in/section/1", оба маркера маршрута выше "регулярного выражения, чтобы представлять что-либо, кроме sign_in" и "/section1/*", оба выполнялись, что означает что первичный макет будет визуализирован, а затем будет выделен вспомогательный макет раздела 1, если это имеет смысл.

Затем все остальные обычные контроллеры используют маршруты в традиционном смысле.

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

Хотелось бы услышать того, кто разработал и внедрил что-то элегантное.