Mozilla's getting a new look. What do you think? https://mzl.la/brandsurvey

Компиляция правил

Шаблон XUL образован запросом и набором правил. Запрос содержит инструкции для выбора набора данных из их источника. Точный синтаксис зависит от типа источника данных, используемого в шаблоне. Например, для источника Sqlite в качестве запроса используется предложение SQL. Запрос возвращает таблицу результатов с данными, на основании которых впоследствии генерируется вывод. Для источников данных RDF и XML запрос содержит инструкции для обхода вершин графа RDF или дерева XML. Запрос объявляется с помощью тэга query, который должен быть размещён прямо под элементом <template> Цель запроса состоит в порождении набора выходных данных.

При использовании упрощённого синтаксиса вы можете опустить элемент <rule>. При этом имеется только одно правило и его употребление подразумевается неявно. С другой стороны, расширенный синтаксис всегда требует наличия элемента <rule>.

Шаблон содержит также набор правил; каждое правило может содержать множество условий для генерации контента. Синтаксис подстановки атрибутов, рассмотренный позже, используется для изменения значения атрибутов элементов, созданных в шаблоне. Каждое правило объявляется с помощью тэга rule; вы можете объявлять несколько правил. Для каждого результата запроса просматриваются условия, определённые правилом, и если они удовлетворяются, генерируется контент. Для каждого результа запроса применяется только первое согласующееся правило. Например, первое правило может быть применено к результатам, соответствующим книгам, тогда как второе правило может быть применено только к результатам, соответствующим журналам. Таким образом, в зависимости от особенностей результирующих данных может быть сгенерирован различный контент.

Во многих случаях вам будет достаточно одного правила, обрабатывающего все данные одинаковым образом. Например, при создании элементов списка вы, скорее всего, будете использовать всего одно правило. В этом случае элемент rule необязателен. Шаблон без правил (или с правилом без условий) сгенерирует вывод для каждого набора выходных данных.

Пока что можем представить синтаксис шаблонов примерно таким образом.

<vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A" flex="1">
  <template>
    <query>
      -- query content goes here --
    </query>
    <rule>
      -- rule content goes here --
    </rule>
    <rule>
      -- rule content goes here --
    </rule>
  </template>
</vbox>

Когда конструктор шаблона начинает загрузку и обработку данных, он, прежде всего, должен скомпилировать запрос и правила. Этот шаг включает обработку правил запроса и их преобразование во внутренние структуры. Таким образом, динамическое изменение правил ни на что не влияет, поскольку они уже скомиплированы. Тем не менее, повторная сборка шаблона (с использованием метода builder.rebuild) повторно скомпилирует запрос и правила и применит их для построения шаблона. Это обозначает, что вы можете динамически изменить правила, используя методы объектной модели документа (DOM), повторно собрать шаблон, и получить новый результат.

Когда конструктор шаблонов скомпилировал правила, он может приступать к обработке запросов и генерации контента. Конструктор генерирует контент лениво (lazily), т.е. обрабатывает столько данных, сколько нужно именно сейчас, и продолжает обработку только тогда, когда это действительно необходимо. Давайте, например, рассмотрим следующий пример:

<vbox datasources="http://www.xulplanet.com/ds/sample.rdf"
         ref="http://www.xulplanet.com/rdf/A" hidden="true">
  <template>
    ...
  </template>
</vbox>

Элемент <vbox> скрыт (hidden="true"). Поскольку любой сгенерированный контент всё равно не будет отображён, конструктор шаблонов ничего не делает, откладывая работу "на потом". Если же вы отобразите элемент vbox (hidden="false"), будет вызван конструктор шаблонов и сгенерирован соответствующий контент.

Означает ли это, что шаблоны не могут быть использованы внутри скрытых областей пользовательского интерфейса? Нет, ибо вы можете использовать их и в этом случае. Изменение свойства hidden не является единственным способом вызова конструктора шаблонов и генерации контента. Вызов программного интерфейса объектной модели документа (DOM API), которому необходимо получить доступ к созданному контенту, заставит конструктор генерировать контент. Например, достаточно вызвать код, подобный приведённому ниже, и внутри скрытого элемента vbox конструктор шаблонов создаст контент.

var length = vbox.childNodes.length;

Таким образом, запрос на количество дочерних узлов элемента vbox заставит конструктор обработать запрос и вывести контент. И только после окончания работы конструктора может быть вычислено требуемое число элементов.

Всё это должно быть очевидно XUL-разработчику. Решение о том, когда конструктор должен начать работу, принимается автоматически; вам для этого ничего особенного делать не нужно. Тем не менее, есть два случая, когда контент не создаётся автоматически: создание меню и дочерних элементов дерева.

Содержимое меню не генерируется до тех пор, пока оно не открыто. Это имеет смысл, поскольку пользователь не может видеть содержимого меню до тех пор, пока оно не открыто. Тем не менее, это означает также, что использование программного интерфейса объектной модели документа (DOM API), такое как попытка получить количество дочерних узлов элемента, не заставит конструктор шаблонов создать содержимое до тех пор, пока пользователь не отобразит меню. Это на самом деле важная особенность. Это означает, что вы не можете полагаться на возможность получения сгенерированных элементов меню до тех пор, пока оно не открыто. Похожее правило применяется к дочерним элементам дерева. Таким образом, дочерние элементы дерева не генерируются до тех пор, пока пользователь либо скрипт не вызвают раскрытие строки в дереве.

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

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

Метки документа и участники

 Внесли вклад в эту страницу: Bektur
 Обновлялась последний раз: Bektur,