Рендеринг макетов с помощью 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...');
}
});
Спасибо
Спасибо, что нашли время ответить. Я ценю это!
Ответы
Ответ 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, если это имеет смысл.
Затем все остальные обычные контроллеры используют маршруты в традиционном смысле.
Должен быть хороший способ управления макетами и гарантировать, что эти макеты, вспомогательные макеты и представления будут снесены безопасно, чтобы обеспечить утечку памяти, среди других причин.
Хотелось бы услышать того, кто разработал и внедрил что-то элегантное.