Расширенная работа с панелями: Библиотека ExtJS для новичков
Эта статья является продолжением учебника по библиотеке компонентов ExtJS, используемой для создания web-приложений с функциональным интерфейсом пользователя.
Как ранее упоминалось при рассмотрении компонента панель – это контейнер для других визуальных компонентов. Пробуем продемонстрировать это, создав две простые панели, одна из которых будет привязываться к окну браузера, а другая пока не будет отображаться:
panel1 = new Ext.Panel({
title: 'Внешняя панель',
collapsible: true,
renderTo: Ext.getBody(),
html: 'Содержимое внешней панели'
});
panel2 = new Ext.Panel({
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели'
});
По пути мы осваиваем еще одно свойство конфигурации панели – collapsible, которое определяет, отрисовывать или нет (true или false) кнопку сворачивания панели в ее заголовке. Для некоторых применений это удобный метод организации информации на экране для сайтов, позволяющих пользователям самим выбирать отображение только актуальных для них данных. Дополнительно с помощью другого свойства titleCollapse можно задать сворачиваемость панели по щелку на ее заголовке.
Далее выполним две магические команды:
panel1.add(panel2) panel1.doLayout()
Первая выполняет метод add панели-контейнера, добавляя в нее дочерние компоненты (в данном случае дочернюю панель). Обратите внимание, что если бы мы имели несколько панелей, их можно было подключить к родительской за один раз, передав их в параметрах метода add: panel1.add(panel2, panel3, panel4…)
Вторая команда сообщает системе отрисовки компонентов выполнить рендер вновь добавленных элементов:
Существует обратное действие – удаление дочернего компонента из панели:
panel1.remove(panel2)
В этом случае после него вызывать doLayout() не требуется, так как основная панель будет перерисована автоматически.
Метод add замечателен тем, что кроме нового дочернего объекта в параметрах может также принимать только саму конфигурацию дочернего объекта и, основываясь на этих данных, динамически создавать новый компонент. Такой подход называется ленивым определением.
Для того чтобы точно знать, какой в этом случае тип компонента создается, необходимо передать в его конфигурации дополнительный параметр xtype. Считайте его внутренним идентификатором определенного вида компонентов. Для ранее рассмотренных нами Panel и Button значениями xtype соответственно являются ‘panel’ и ‘button’. Список всех доступных значений xtype можно получить в Приложении А.
В следующем примере мы добавим к внешней панели еще одну дочернюю, задав ее с помощью ленивого определения:
panel1.add({
xtype: 'panel',
title: 'Ленивая панель',
collapsible: true,
html: 'Содержимое ленивой панели'});
panel1.doLayout()
Выше мы рассмотрели динамическое добавление дочерних элементов к панели, но том случае, если на этапе создания базовой панели уже известны ее составляющие, можно все компоненты указать в параметре items
Обычное определение:
panel1 = new Ext.Panel({
title: 'Внешняя панель',
collapsible: true,
renderTo: Ext.getBody(),
html: 'Содержимое внешней панели',
items: [
new Ext.Panel({
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели'
})
]
});
Ленивое определение:
panel1 = new Ext.Panel({
title: 'Внешняя панель',
collapsible: true,
renderTo: Ext.getBody(),
html: 'Содержимое внешней панели',
items: [
{
xtype: 'panel',
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели'
}
]
});
Обратите внимание, что в свойстве items мы использовали индексный массив, который позволяет задавать сразу несколько дочерних элементов. При определении только одного элемента для удобства квадратные скобки можно опустить.
Использовать ленивое определение компонентов рекомендуется во всех случаях, когда это возможно. Во-первых, уменьшается количество операций по отрисовке компонентов, позволяя провести их за один раз – при создании родительского. Во-вторых, это гарантирует потребление меньших объемов памяти и системных ресурсов из-за сокращения числа используемых объектов. Кроме того, если родительская панель вообще не будет отображена (например, находится на другом табе, который пользователь не нажмет при просмотре страницы), дочерние элементы так и не будут созданы, а следовательно на эти операции не будут потрачены ресурсы.
Продемонстрируем как свойство items может содержать несколько элементов разных типов:
panel1 = new Ext.Panel({
title: 'Внешняя панель',
collapsible: true,
renderTo: Ext.getBody(),
html: 'Содержимое внешней панели',
items: [
{
xtype: 'panel',
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели'
}, {
xtype: 'button',
text: 'Кнопка 1',
}, {
xtype: 'button',
text: 'Кнопка 2',
}
]
});

Неуказание xtype при ленивом определении компонента не является ошибкой: библиотека воспользуется типом компонента по-умолчанию (в случае панели и большинства других визуальных компонентов их дочерние элементы также будут панелями). Если вы хотите изменить тип дочерних элементов по-умолчанию, воспользуйтесь свойством конфигурации defaultType.
Удалять дочерние элементы, указанные в случае ленивого определения, можно через определение их идентификаторов (id):
panel1 = new Ext.Panel({
title: 'Внешняя панель',
collapsible: true,
renderTo: Ext.getBody(),
html: 'Содержимое внешней панели',
items: [
{
xtype: 'panel',
id: 'panel2',
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели'
}
]
});
panel1.remove(Ext.getCmp('panel2'));
Если все элементы панели должны иметь ряд свойств с одинаковыми значениями, в конфигурации можно определить свойство defaults и в нем задать требуемые параметры.
Существуют так называемые плавающие панели, которые имеют четко заданные координаты относительно страницы документа. В этом случае необходимо определить размеры компонента (свойства width и height в конфигурации), признак плавающей панели (свойство floating = true), после чего задать ее абсолютные координаты методом setPosition(X, Y):
panel = new Ext.Panel({
title: 'Плавающая панель',
floating: true,
width: 300,
height: 150,
renderTo: Ext.getBody(),
html: 'Какое-то важное сообщение'
});
panel.setPosition(100, 200);

По умолчанию у плавающей панели отрисовывается тень, которая визуально как бы приподнимает ее над другими элементами документа. Необходимость отрисовки тени и способ определяется свойством конфигурации shadow.
Панели могут быть довольно сложными и содержать кроме дочерних элементов верхний и нижний тулбар и нижние внешние кнопки:
new Ext.Panel({
title: 'Сложная панель',
renderTo: Ext.getBody(),
html: 'HTML-код',
tbar: [
{ text: 'Верхняя кнопка 1' },
{ text: 'Верхняя кнопка 2' }
],
bbar: [
{ text: 'Нижняя кнопка 1' },
{ text: 'Нижняя кнопка 2' }
],
buttons: [
{ text: 'Кнопка 1' },
{ text: 'Кнопка 2' }
],
items: [
{ title: 'Панель 1', html: 'Панель 1' },
{ title: 'Панель 2', html: 'Панель 2' }
]
})

Что еще можно делать с панелями?
- Панель может иметь заголовок (свойство title в конфигурации), а может не иметь его. В этом случае компонент становится обычным контейнером других компонентов.
- Конечные размеры панели как и многих визуальных компонентов задаются свойствами height и width в конфигурации (либо auto по-умолчанию, либо числовые значения в пискелах)
- С помощью свойства autoLoad можно задать URL, с которого будет выполняться загрузка тела панели с помощью внутреннего AJAX запроса. Точно такое же действие можно выполнить в любой момент после создания панели с помощью метода load. Существует ограничение, связанное с системой безопасности браузеров, которое не позволяет использовать разные серверы для основной страницы и запроса к подгружаемому содержимому.
- Если содержимое тела панели не вмещается в заданную область, можно задать автоматическую активацию полос прокрутки при необходимости (свойство autoScroll в конфигурации компонента).
- Можно управлять отображением рамок панели (свойства bodyBorder, border, hideBorders и frame в конфигурации компонента).
- Выравнивание кнопок панели может быть правым (по-умолчанию), левым или по центру (свойство buttonAlign в конфигурации компонента).
- Панель при начальном отображении на эране может быть в уже свернутом режиме (свойство collapsed в конфигурации компонента)
Продолжение следует…
Перейти к содержанию Учебника по ExtJS


Спасибо за материал!
Я яваскрипты не так давно начал изучать. И в ексте совсем новичок. Статьи очень помогли разобрать с базовыми элементами!
И с FireBug’oм научился работать)))
С уважением, Константин!!!!!!
Удачи!!!
очень полезное дело, пишите больше. Очень понравилось но мало. Расскажите о там как работать с документацией, было бы здорово.
Огромное спасибо за материал и за проделанную работу!!!
Очень хотелось бы почитать продолжение – особенно по взаимодействию с сервером (JSON, Reader, Grid)
у меня почемуто вот это пример не воспроизводится:
panel1 = new Ext.Panel({
title: ‘Внешняя панель’,
collapsible: true,
renderTo: Ext.getBody(),
html: ‘Содержимое внешней панели’,
items: [
{
new Ext.Panel({
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели'
})
}
]
});
выскакивает такая ошибка:
missing : after property id
[Break on this error] new Ext.Panel({\n
Действительно, в пример закралась ошибка (лишние фигурные скобки, обрамляющие дочерний объект панели). Правильный вариант:
panel1 = new Ext.Panel({
title: ‘Внешняя панель’,
collapsible: true,
renderTo: Ext.getBody(),
html: ‘Содержимое внешней панели’,
items: [
new Ext.Panel({
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели'
})
]
});
Не знаю с чем связанно, скорее всего в версиях Ext_а, следующий код приведенный в примере не рабочий (приминительно к последней на сегодня – 3.0 версии) -
panel1 = new Ext.Panel({
title: ‘Внешняя панель’,
collapsible: true,
renderTo: Ext.getBody(),
html: ‘Содержимое внешней панели’,
items: [
{
xtype: 'panel',
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели'
}, {
xtype: 'button',
text: 'Кнопка 1',
}, {
xtype: 'button',
text: 'Кнопка 2',
}
]
});
необходимо писать так -
panel1 = new Ext.Panel({
title: ‘Внешняя панель’,
collapsible: true,
renderTo: Ext.getBody(),
html: ‘Содержимое внешней панели’,
items: [
{
xtype: 'panel',
title: 'Внутреняя панель',
collapsible: true,
html: 'Содержимое внутренней панели',
buttons: [
{text: 'Кнопка 1'},
{text: 'Кнопка 2'}
]
}]
});
С Уважением к Автору статьи.
Спасибо за статью, вообще нет книг по этому фреймворку спасибо за такие крупицы