Реализация генерируемого содержимого

Давайте реализуем генерируемое содержимое на нашем Web-сайте. Мы создадим базу данных, содержащую список всех Web-страниц (файлов с подгружаемым содержимым) с названиями и гиперссылками.

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

• В следующей главе мы осуществим вывод на каждой Web-странице раздела "См. также", в котором поместим гиперссылки на Web-страницы с "родственными" данными.

• В последующих главах мы организуем поиск нужной Web-страницы, опять же, на основе данных, хранящихся в этой базе.

Для генерирования содержимого Web-страницы мы применим соответствующие методы объекта Element библиотеки Ext Core. Этих методов довольно много, и не составит труда выбрать подходящий.

Создание базы данных

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

Наша база данных будет представлять собой три массива, хранящие списки Web-страниц, которые описывают, соответственно, теги HTML, атрибуты стиля CSS и примеры. Элементы массивов будут хранить конфигураторы, описывающие эти Web-страницы и хранящие их названия и интернет-адреса в виде строк.

Создадим текстовый файл с именем data.js и поместим его в папке Site 2. Откроем его и наберем код, приведенный в листинге 18.1.

Создание базы данных

Здесь мы объявили массивы aHTML, aCSS и aSamples, которые будут хранить списки Web-страниц, описывающих, соответственно, теги HTML, атрибуты стиля CSS и примеры.

Элементы каждого из этих массивов хранят конфигураторы с двумя свойствами:

name — название соответствующего пункта вложенного списка в виде строки;

url — интернет-адрес файла с фрагментом содержимого также в виде строки.

Сохраним набранный код в кодировке UTF-8. Вообще, не забываем, что после любых правок кода его нужно сохранять.

Затем откроем в Блокноте Web-страницу index.htm и вставим в ее секцию заголовка такой код:

<SCRIPT SRC="data.js"></SCRIPT>

Он загрузит и выполнит только что созданный нами файл Web-сценария data.js. В результате в памяти компьютера будут созданы три массива — наша база данных.

Отметим, что файл Web-сценария загружается и выполняется в самом начале загрузки Web-страницы index.htm. Поэтому, когда дело дойдет до исполнения Web-сценариев, хранящихся в файле main.js (а они выполняются в конце загрузки Web-страницы), наша база данных уже будет сформирована и готова к работе.

Генерирование полосы навигации

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

Снова откроем Web-страницу index.htm в Блокноте, если уже ее закрыли. Удалим весь HTML-код, формирующий пункты вложенных списков в полосе навигации, но оставим фрагмент, создающий сами вложенные списки. Результат приведен в листинге 18.2.

Реализация генерируемого содержимого

После этого откроем файл Web-сценария main.js и поместим перед вызовом метода onReady объекта Ext код из листинга 18.3.

Генерирование полосы навигации

Он объявляет функцию generateInnerList, которая будет создавать пункты одного вложенного списка. Эта функция принимает два обязательных параметра:

• один из формирующих нашу базу данных массивов; на основе этого массива будут созданы пункты указанного вложенного списка;

• вложенный список, в котором будут создаваться эти пункты, в виде экземпляра объекта Element.

Ее код очень прост. Рассмотрим его построчно.

Запускаем цикл со счетчиком, в теле которого будут создаваться пункты списка:

for (var i = 0; i < aDataBase.length; i++) {

Счетчик цикла — переменная i, начальное значение счетчика — 0, конечное значение — размер массива, переданного первым параметром (он берется из свойства length объекта Array; подробнее — в главе 14), приращение — инкремент счетчика. В результате цикл выполнится столько раз, сколько элементов содержит массив, переданный первым параметром.

Формируем строку с HTML-кодом, создающим пункт списка:

var s = "<LI><CODE><A HREF=\"" + aDataBase[i].url + "\">" +

aDataBase[i].name + "</A></CODE></LI>";

Название пункта и интернет-адрес файла с фрагментом содержимого берем из соответствующих свойств конфигуратора, являющегося элементом переданного первым параметром массива.

Создаем пункт списка на основе строки, сформированной в предыдущем выражении:

elInnerList.insertHtml("beforeEnd", s);

}

В качестве места, куда будет помещен новый пункт, мы указываем "beforeEnd" — перед закрывающим тегом. В результате новые пункты будут добавляться в конец списка.

На этом выполнение тела цикла завершается. А после того, как цикл закончит работу, завершится выполнение самой функции generateInnerList.

Теперь вставим в самое начало тела функции, передаваемой методу onReady объекта Ext, три выражения:

generateInnerList(aHTML, Ext.get("navbar").child("> LI:nth(1) UL"));

generateInnerList(aCSS, Ext.get("navbar").child("> LI:nth(2) UL"));

generateInnerList(aSamples, Ext.get("navbar").child("> LI:nth(3) UL"));

Мы трижды вызываем функцию generateInnerList, поочередно передавая ей три массива, составляющих базу данных, и три вложенных списка, формирующих полосу навигации.

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

Сортировка базы данных

Итак, Web-сценарий, генерирующий полосу навигации, работает. Самое время дополнить полосу навигации еще парой пунктов.

Откроем файл Web-сценария data.js и добавим в массив aCSS два элемента:

aCSS[3] = { name: "font-family", url: "attrs/a_font-family.htm" };

aCSS[4] = { name: "font-size", url: "attrs/a_font-size.htm" };

Откроем Web-страницу index.htm в Web-обозревателе. И обнаружим, что во втором вложенном списке (перечисляющем атрибуты стиля CSS) появятся два новых пункта. Причем они окажутся в самом его конце, нарушив принятый нами алфавитный порядок.

Дело в том, что эти два новых элемента мы добавили в самый конец массива aCSS. Функция generateInnerList "пройдет" по этому массиву и создаст новые пункты в том порядке, в котором соответствующие элементы в нем присутствуют.

Но мы-то хотим, чтобы они выводились в алфавитном порядке! Значит, нужно как-то отсортировать массив aCSS.

Специально для таких случаев объект JavaScript Array поддерживает метод sort. Он как раз и выполняет сортировку массива, у которого вызван:

<массив>.sort([<функция сравнения>])

Если этот метод был вызван без параметров, он отсортирует массив по строковому представлению его элементов. Каждый элемент массива он преобразует в строку и отсортирует элементы по алфавитному порядку этих строк (а если точнее, то по кодам символов, составляющих эти строки).

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

Но метод sort поддерживает необязательный параметр — функцию сравнения, которая поможет нам отсортировать элементы массива как нам нужно.

Функция сравнения должна принимать два параметра — сравниваемые элементы массива — и возвращать число, указывающее, какой из этих элементов с точки зрения программиста "меньше".

• Если первый элемент "меньше" второго, функция сравнения должна вернуть отрицательное число (обычно –1).

• Если оба элемента "равны", функция сравнения должна вернуть 0.

• Если первый элемент "больше" второго, функция сравнения должна вернуть положительное число (обычно 1).

Давайте напишем функцию (листинг 18.4), которая будет сравнивать элементы массивов aHTML, aCSS и aSamples по значению свойства name конфигуратора. Сравнивать строки мы будем с помощью знакомых нам по главе 14 операторов сравнения — они прекрасно работают и со строками.

Сортировка базы данных

Поместим код листинга 18.4 в самом конце файла Web-сценария data.js, после объявлений всех трех массивов.

Осталось только, собственно, выполнить сортировку массивов. Это сделают три следующих выражения, которые мы поместим после объявления функции сравнения:

aHTML.sort(sortArray);

aCSS.sort(sortArray);

aSamples.sort(sortArray);

Проверим Web-страницу index.htm в действии и убедимся, что пункты во вложенных списках расположены в алфавитном порядке.