HTML компилятор в AngularJS

| Пятница, 12 июля, 2013

Метки: AngularJS Комментарии: 0

HTML-компилятор AngularJS позволяет разработчикам научить браузеры понимать новый синтаксис HTML. То есть можно добавлять новое поведение для HTML элементов и атрибутов. А также создавать новые HTML элементы или атрибуты с любым поведением. В Angular эти новые элементы называются директивами.

HTML имеет богатый набор элементов разметки для форматирования статических документов в декларативной манере. Например, если что-то нужно разместить в центре страницы, то не надо писать специально код, чтобы найти центр страницы , затем найти смещение от центра на половину ширины элемента. Мы просто добавляем атрибут align="center" к любому элементу, чтобы добиться нужного поведения. В этом и есть вся сила декларативного языка.

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

Angular поставляется со многими встроенными новыми директивами, которые очень полезны для разработки приложений. Но и разработчики могут создавать свои собственные директивы, специфичные для конкретных приложений. Эти расширения становятся предметно-ориентированным языком (Domain Specific Language), специально предназначенным для разработки определенных приложений.

Вся компиляция происходит в браузере на стороне клиента, а не на сервере, и без предварительной компиляции.

Компилятор

Компилятор - это сервис в Angular, который делает обход DOM элементов для поиска атрибутов. Процесс компиляции происходит в два этапа.

  1. Компиляция: происходит обход элементов DOM и сбор всех директив.
  2. Связывание: Распределение директив по объектам scope (область видимости) и выдача готового представления. Все изменения в модели scope сразу отражаются на представлении. Таким образом, модели scope являются первоисточниками данных, от которых зависит все остальное.

Некоторые директивы типа ng-repeat клонируют элементы DOM для каждого элемента коллекции. Поэтому наличие двух этапов обработки, - компиляции и связывания, увеличивают производительность, так как шаблон для клонирования компилируется один раз, и затем происходит связывание каждого клонированного экземпляра.

Директивы

Директива – это поведение, которое должно быть запущено, если определенная конструкция HTML встретилась во время компиляции. Директивы могут быть заданы через имена элементов, атрибуты, названия классов, а также комментарии. Ниже пример использования директивы ng-bind разными способами:

<span ng-bind="exp"></span>
<span class="ng-bind: exp;"></span>
<ng-bind></ng-bind>
<!-- directive: ng-bind exp -->

Директива - это просто функция, которая выполняется, когда компилятор нашел ее в DOM. Полная и подробная документация по написанию директив находится здесь.

Ниже пример директивы,которая делает любой элемент сделать перетаскиваемым (draggable). Обратите внимание на атрибут draggable в элементе .

<!doctype html>
<html ng-app="drag">
<head>
   <script src="http://code.angularjs.org/1.0.6/angular.min.js"></script>
   <script src="script.js"></script>
</head>
<body>
   <span draggable>Drag ME</span>
</body>
</html>
     
      
angular.module('drag', []).
  directive('draggable', function($document) {
    return function(scope, element, attr) {
      var startX = 0, startY = 0, x = 0, y = 0;
      element.css({
        position: 'relative',
        border: '1px solid red',
        backgroundColor: 'lightgrey',
        cursor: 'pointer'
      });
      element.bind('mousedown', function(event) {
        // Prevent default dragging of selected content
        event.preventDefault();
        startX = event.screenX - x;
        startY = event.screenY - y;
        $document.bind('mousemove', mousemove);
        $document.bind('mouseup', mouseup);
      });
	 
      function mousemove(event) {
        y = event.screenY - startY;
        x = event.screenX - startX;
        element.css({
          top: y + 'px',
          left: x + 'px'
        });
      }
	 
      function mouseup() {
        $document.unbind('mousemove', mousemove);
        $document.unbind('mouseup', mouseup);
      }
    }
  });
Живой пример
Перетащи меня

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

Генерация представления

Существует много систем, использующих шаблоны. Большинство из них принимают шаблон в виде текста и комбинируют его с данными, что на выходе дает новый текст. Потом этот текст вставляется в элемент при помощи метода innerHtml.

С таким механизмом после любого изменения данных должно быть выполнено слияние с шаблоном, и затем результат нужно опять вставить в innerHTML. Большим минусом такого подхода является сложная обработка данных, введенных пользователем. Например, сначала нужно прочитать данные из представления, изменить данные модели, выполнить слияние с шаблоном и затем грубо переписать данные, путем вставки нового представления.

Angular работает совсем по-другому. Angular компилятор принимает DOM вместе с директивами, но не текстовые шаблоны. На выходе мы получаем связующую функцию, которая сливаясь с моделью данных scope, выдает интерактивное представление. Представление и scope-модель связаны двусторонне. Разработчику не надо ничего делать для обновления представления. И так как не используется вставка разметки в innerHtml, то представление не перезаписывается грубо при изменении данных. Директивы Angular могут не только выступать в качестве связки между элементами представления и данными, но и обладать поведенческими функциями.

После компиляции Angular выдает стабильный, устойчивый DOM. Это значит, что экземпляры DOM элементов, связанные с переменными модели, не изменяются в течении всего периода связывания. И это значит, что если в коде к DOM элементам прикрепляются события, то можно не бояться, что эти события могут пропасть из-за обновления или слияния с шаблоном.

Комментарии
Никто еще не оставил здесь комментарий.
Войдите, чтобы написать комментарий , или воспользуйтесь формой ниже.
 

Copyright © CodeHint.ru 2013-2024 (v2.4.7 - работает на Angular Universal)Калькулятор инвест-портфеля