Статьи

Улучшение веб-приложений с помощью AmplifyJS

Кажется, каждую неделю появляется новый набор специализированных библиотек JavaScript. Похоже, прошли те времена, когда в проекте использовалась только одна библиотека. Сегодня я познакомлю вас с очень классной библиотекой компонентов, AmplifyJS , которая предлагает всего несколько очень специализированных компонентов.


По данным сайта :

AmplifyJS — это набор компонентов, предназначенных для решения типичных проблем веб-приложений.

Звучит престижно, но что на самом деле в этой библиотеке?

AmplifyJS состоит из трех основных частей:

  • AJAX API
  • Система событий PubSub
  • API хранилища на стороне клиента

Присоединяйтесь ко мне сейчас для экскурсии по невероятной библиотеке AmplifyJS! Мы собираемся создать очень простой трекер сотрудников; на самом деле, это просто таблица с несколькими функциями, похожими на приложения, любезно (частично) из AmplifyJS.

Сегодня нам не нужно заниматься вопросами стилей и макетов, поэтому я собираюсь использовать библиотеку Twitter Bootstrap . Это невероятно просто: просто добавьте link на файл CSS, который позволяет вам использовать горячую link с Github, и вы в деле.


Итак, создайте себе каталог проектов. Начните с файла index.html и папки js . Теперь зайдите на сайт AmplifyJS и нажмите эту огромную красную кнопку «скачать». Однажды у вас есть zip библиотеки, распакуйте ее и переместите в папку js . Нам понадобятся еще несколько вещей:

  • jQuery: AJAX-компонент Amplify использует функцию AJAX jQuery под своим API, по крайней мере по умолчанию. Но мы будем использовать jQuery для других вещей, так что включите его.
  • bootstrap-modal.js : библиотека Twitter Bootstrap включает в себя несколько скриптов для получения всех интерактивных. И мы собираемся использовать один: модальный оконный плагин jQuery . Загрузите его и добавьте в папку js .
  • По пути я упомяну еще два сценария, но мы напишем их сами.

Затем запустите наш файл index.html следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE HTML>
<html>
  <head>
    <title>AmplifyJS</title>
    <link rel=’stylesheet’ href=’http://twitter.github.com/bootstrap/1.3.0/bootstrap.min.css’ />
  </head>
  <body>
    <div class=’container’>
      <div class=’row’>
        <div class=’span16′ id=’alert-area’>
        </div>
      </div>
      <div class=’row’>
        <div class=’span4′>
            <h2>Commands</h2>
        </div>
        <div class=’span12′>
          <h1>Employees</h1>
        </div>
      </div>
    </div>
    <script src=’https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js’></script>
    <script src=’js/amplify/amplify.min.js’></script>
    <script src=’js/bootstrap-modal.js’></script>
  </body>
</html>

Если вы не знакомы с использованием Twitter Bootstrap, вы увидите, что использовать его не стоит. У нас есть container шириной 940 пикселей. Тогда у нас есть две row с. Первый имеет один столбец, который охватывает все 16 столбцов. Другой имеет два столбца: один имеет ширину 4 столбца, а другой — 12 столбцов.

Еще одна вещь, прежде чем мы перейдем к некоторому реальному кодированию: мы собираемся открыть модальное окно, которое позволяет вводить сотрудников. Под <div class='container'> добавьте это модальное окно HTML. Да, похоже, много кода, но в основном это Bootstrap:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div id=’add-employee-modal’ class=’modal fade’>
  <div class=’modal-header’>
    <a href=’#’ class=’close’>x</a>
    <h3>Add an Employee</h3>
  </div>
  <div class=’modal-body’>
    <form id=’employee-form’>
      <div class=’clearfix’>
        <label for=’firstName’>First Name:</label>
        <div class=’input’><input type=’text’ name=’firstName’ placeholder=’John’ /></div>
      </div>
      <div class=’clearfix’>
        <label for=’lastName’>Last Name:</label>
        <div class=’input’><input type=’text’ name=’lastName’ placeholder=’Doe’ /></div>
      </div>
      <div class=’clearfix’>
        <label for=’role’>First Name:</label>
        <div class=’input’><input type=’text’ name=’role’ placeholder=’Designer’ /></div>
      </div>
    </form>
  </div>
  <div class=’modal-footer’>
    <button id=’create-employee’ class=’btn primary’>Add</button>
  </div>
</div>

Хорошо, мы готовы к работе! Давайте код.


Откройте тег script в нижней части index.html (я просто делаю это встроенным, но чувствую, что помещаю его в новый файл JS). начните так:

1
2
3
4
(function () {
   var employeeModal = $(‘#add-employee-modal’).modal({ backdrop: ‘static’ });
 
 }());

Мы используем модальный плагин Bootstrap здесь; это просто «создает экземпляр» модального окна. Теперь мы хотим, чтобы окно появлялось при нажатии кнопки «Добавить сотрудника». Конечно, сначала нам нужно добавить кнопку: поместите ее в <div class='span4'> , прямо под <h2> .

1
<p><button id=’add-employee’ data-controls-modal=’add-employee-modal’ class=’btn’>Add Employee</button></p>

Этот атрибут data-controls-modal='add-employee-modal' будет отображать модальность с указанным идентификатором при нажатии кнопки.

Итак, пользователю нужно будет заполнить форму, нажмите кнопку «Добавить», которая имеет идентификатор create-employee . Итак, давайте подключим обработчик события click для кнопки:

01
02
03
04
05
06
07
08
09
10
$(‘#create-employee’).click(function () {
    var form = $(‘#employee-form’);
    employeeModal.modal(‘hide’);
    EMPLOYEE.create(
        form.find(‘[name=firstName]’).val(),
        form.find(‘[name=lastName]’).val(),
        form.find(‘[name=role]’).val()
    );
    form.find(‘input’).val(»);
});

Мы получаем форму, а затем скрываем модальное окно. Затем мы будем вызывать метод EMPLOYEE.create , передавая имя, фамилию и роль в качестве трех параметров. Наконец, мы очищаем форму.

Но подождите, вы говорите, что такое EMPLOYEE.create ? Ну, это микро-класс, который я поместил в js/employee.js . Проверьте это:

01
02
03
04
05
06
07
08
09
10
11
12
var EMPLOYEE = {
    create : function (firstName, lastName, role) {
       var employee = {
            firstName: firstName,
            lastName: lastName,
            role: role,
            dateEmployed: new Date()
       };
       amplify.publish(’employee-created’, employee );
       return employee;
    }
};

Вы хотите бросить тег сценария для этого с другими.

Довольно просто, правда? Мы просто создаем литерал объекта с нашими параметрами и добавляем свойство dateEmployed . Но тогда — и наконец! — у нас есть первый вход в среду AmplifyJS. Здесь мы используем компонент pub / sub events. Это отлично подходит для слабой связи между частями вашего приложения.

Этот метод не должен знать, хочет ли другая часть нашего кода что-то делать с каждым новым сотрудником, которого мы создаем; Наш обработчик событий кнопки «Добавить» не должен беспокоиться об этом. Мы просто опубликуем его как событие, созданное сотрудником, для любой части, которая заинтересована принять участие. Мы передаем наш новый объект сотрудника как данные для всех, кто заинтересован. Затем мы возвращаем объект employee (даже если мы не отслеживаем его в нашем обработчике событий).


Итак, интересует ли какая-либо другая часть нашего приложения «созданный сотрудником»? Да на самом деле. Мы хотим сделать две вещи. Сначала добавьте этого сотрудника в таблицу на нашей странице. Во-вторых, мы хотим хранить сотрудника в localStorage. Вот первая часть этого:

1
2
3
4
amplify.subscribe(’employee-created’, function (employee) {
   employeeTable.add([employee.firstName, employee.lastName, employee.role, employee.dateEmployed]);
   newAlert(‘success’, ‘New Employee Added’);
 });

Чтобы подписаться на событие, мы вызываем amplify.subscribe . Мы хотим подписаться на «сотрудник создан»; когда эти события происходят, мы хотим добавить их в employeeTable ; обратите внимание, что вместо того, чтобы просто передавать объект объекта employee , мы «конвертируем» его в массив; это потому, что мы должны быть уверены, что элементы будут в правильном порядке. Затем мы хотим отобразить сообщение, сообщающее нашему пользователю, что сотрудник был успешно добавлен.

Что случилось с этой переменной employeeTable ? Ну, во-первых, мы должны добавить <table> в наш документ. Итак, под нашими «сотрудниками» <h1> добавьте:

01
02
03
04
05
06
07
08
09
10
11
12
<table id=’employee-table’ class=’zebra-striped’>
    <thead>
        <tr>
            <th> First Name </th>
            <th> Last Name </th>
            <th> Role </th>
            <th> Date Employed </th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

Теперь нам нужно захватить эту таблицу как переменную в нашем выражении var вверху:

1
employeeTable = TABLE.create($(‘#employee-table’)),

А TABLE ? Это последний кусок JS для этой головоломки. Поместите это в js/table.js и не забудьте тег script:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var TABLE = {
    proto : {
        init : function (el) {
            this.element = $(el).find(‘tbody’);
        },
        add: function (arr) {
            var row = $(‘<tr>’).html(function () {
                return $.map(arr, function (value) {
                    return ‘<td>’ + value + ‘</td>’;
                }).join(»);
            });
            this.element.append(row);
        },
        load: function (rows, order) {
            for (var i = 0; rows[i]; i++ ) {
                this.add(rows[i]);
            }
            var fields = [];
            for (var j = 0; order[j]; j++) {
                fields.push(rows[i][order[j]]);
            }
                this.add(fields);
        },
        clear: function () {
            this.element.empty();
        }
    },
    create : function (el) {
        var table = Object.create(this.proto);
        table.init(el);
        return table;
    }
};

Это немного сложно, но у вас не должно быть проблем с этим. У нас есть свойство proto которое является прототипом для наших экземпляров таблицы. Затем, когда мы вызываем create , мы используем Object.create для создания объекта, который наследуется от this.proto . После этого мы вызываем метод init для установки любых свойств. Наконец, мы возвращаем экземпляр таблицы.

Этот микро-API облегчает нам работу с нашим столом. Вы должны увидеть, как передача массива в метод add добавит строку в нашу таблицу. Также обратите внимание, что мы можем передать массив строк для load и заполнения таблицы; мы будем использовать это в ближайшее время.

О, тогда есть метод newAlert который мы вызвали:

1
2
3
4
5
6
7
function newAlert (type, message) {
    $(‘#alert-area’).append($(‘<div class=’alert-message ‘ + type + ‘ fade in’ data-alert><p> ‘ + message + ‘ </p></div>’));
 
    setTimeout(function () {
        $(‘.alert-message’).fadeOut(‘slow’, function () { this.parentNode.removeChild(this); });
    }, 2000);
}

Как видите, это просто добавляет div наизнанку <div id='alert-area'> ; новый div использует преимущества стиля Twitter Bootstrap; через две секунды мы отключаем оповещение и удаляем его.

Но это не единственная мысль, которую мы хотим сделать, когда происходит событие «созданный сотрудником»:

1
employeeStore = amplify.store(’employees’) ||

Вверху, с двумя другими нашими переменными, создайте третью и последнюю переменную: employeeStore . Если amplify.store('employees') возвращает что-то, мы будем использовать это; в противном случае мы будем использовать пустой массив.

1
2
3
4
amplify.subscribe(’employee-created’, function (employee) {
    employeeStore.push(employee);
    amplify.store(’employees’, employeeStore);
});

Теперь мы используем компонент хранения AmplifyJS. Это действительно не может быть проще: сохранить значение, передать amplify.store ключ и значение. Чтобы получить значение, передайте ему ключ. Ниже AmplifyJS хранит этот ключ и значение в любом типе хранилища, доступном в этом браузере.

Итак, мы добавляем нового сотрудника в массив и сохраняем массив в ключе сотрудников. Я должен отметить, что, поскольку мы храним массив, AmplifyJS использует сериализацию JSON для преобразования этого массива в строку. Поэтому, если вы пытаетесь поддерживать браузеры без встроенной поддержки JSON (IE 5 и ниже, Firefox 3 и ниже), вам нужно включить библиотеку json2.js .


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

Начнем с добавления кнопки для загрузки данных.

1
<p><button id=’push-data’ class=’btn’>Push Data to Server</button></p>

Теперь, конечно, ваши блестящие умы уже поняли, что мы будем использовать компонент AJAX AmplifyJS. amplify.request — невероятно гибкий API, и мы не будем рассматривать все, что он может сделать. Тем не менее, вы получите хорошее представление о том, как это работает здесь.

Работа с AJAX с AmplifyJS немного отличается от работы с другими библиотеками: идея в том, что сначала вы определяете соединение с сервером; затем вы можете использовать это соединение любое количество раз после этого. Давайте начнем с определения соединения, которое AmplifyJS называет «ресурсом»:

1
2
3
4
amplify.request.define(‘pushData’, ‘ajax’, {
    url: ‘data.php’,
    type: ‘POST’
});

Первый параметр здесь — это resourceId , который мы устанавливаем как «pushData»; это то, как мы будем ссылаться на наше соединение, когда мы его используем. Второй параметр — это тип запроса; в данном случае «ajax». Это единственный тип запроса, встроенный в AmplifyJS; Вы можете добавить свои собственные, но это подходит для наших нужд сегодня.

Наконец, у нас есть объект параметров. Согласно документации, вашими параметрами настройки являются все, что вы бы задали в jQuery.ajax , а также cache (который позволяет настроить кеш пользовательской памяти) и decoder (для анализа ответа AJAX). В нашем случае необходимы только две опции: url и type запроса, который мы делаем.

Конечно, нам понадобится простой PHP на конце; убедитесь, что папка data доступна для записи.

1
2
3
4
5
6
7
8
<?php
   $employees = json_encode($_POST[’employees’]);
   $file = fopen(‘data/data.json’,’w+’);
   fwrite($file, $employees);
   fclose($file);
 
   echo ‘success’;
?>

Теперь, как насчет использования соединения, ресурса, который мы определили? Что ж, давайте сделаем это в обработчике кликов для этого <button id='push-data'> :

1
2
3
4
5
$(‘#push-data’).click(function () {
    amplify.request(‘pushData’, { employees: amplify.store(’employees’) }, function (data) {
        amplify.publish(‘data-pushed’, data);
    });
});

При использовании ресурса первым параметром является идентификатор ресурса; это тот же идентификатор ресурса, который у нас есть определенный ресурс, поэтому AmplifyJS знает, какой использовать. Во-вторых, мы передаем хэш данных. В этом случае мы передаем содержимое в нашем магазине под ключом «сотрудники». Последний параметр — это функция, которая вызывается, когда мы получаем ответ.

Как только мы получим ответ, мы опубликуем событие «отправка данных». Затем мы просто предупредим пользователя, что это сработало:

1
2
3
amplify.subscribe(‘data-pushed’, function () {
    newAlert(‘success’, ‘Data successfully sent to server’);
});

Ну, это наш маленький пример приложения. Мы рассмотрели использование всех трех компонентов amplify.publish / amplify.subscribe : amplify.publish / amplify.subscribe , amplify.store и amplify.request . Мы рассмотрели почти все, что нужно знать о pubsub и частях магазина (их немного больше!), Но с API запросов можно сделать гораздо больше. Итак, зайдите на сайт, чтобы узнать больше !

Итак, что вы думаете об AmplifyJS? Нравится? Считаете это слишком избыточным? Давайте послушаем это в комментариях!