Планировщик в режиме реального времени на AngularJS и Firebase

demo

Приложения, которые поддерживают взаимодействие в режиме реального времени расширяют границы стандартного функционала веб-приложений: совместное редактирование документов в Google Drive, отображение новых сообщений в Twitter, чаты новых поколений и многое-многое другое.

Конечно же неплохо было бы знать, как подобный функционал конструируется при помощи socket.io и Node.js.

Однако, есть ещё один способ создания подобных приложений с помощью классного сервиса Firebase.

Что такое Firebase

Firebase представляет собой API сервис для хранения и синхронизации данных в режиме реального времени. Это позволяет не ломать голову насчёт сервера, базы данных или о компонентах, обеспечивающих режим реального взаимодействия (socket.io). Всё это сделает Firebase.

Просто забираем данные из Firebase, отправляем данные в Firebase, и Firebase позаботится о сохранении и синхронизации между всеми подключёнными устройствами/сайтами!

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

Firebase тесно сотрудничает с Google, так что это некая гарантия того, что у платформы есть надёжная поддержка, и в будущем она будет только расти.

Вот несколько простых демо-примеров. Нажмите на кнопку Play для того, чтобы увидеть чат в режиме реального времени. Так же кликните на ссылку вида https://xxxxxxxx.firebaseio-demo.com для того, чтобы увидеть обновления, которые происходят в Firebase. В данной панели можно увидеть наши данные и процесс их изменения.

Для большего понимания, как можно взаимодействовать с данной платформой, давайте создадим простое приложение с использованием Firebase.

Наше тестовое приложение

Мы собираемся создать небольшой планировщик, где люди могут выбрать время для встречи с вами. Это будет простой аналог чего-то вроде youcanbook.me. Так же мы хотим чтобы данные менялись в режиме реального времени.

Требования:

  • Отображение доступных дат
  • Если кто-то кликнул на слот, то нужно отключить его для всех остальных пользователей
  • Для фронт-энда используем AngularJS/HTML/CSS
  • Для бэк-энда Firebase

Вот небольшое демо. Слева вы можете увидеть наше приложение с возможным временем встречи. Справой стороны, панель Firebase где можем увидеть как данные взаимодействуют в режиме реального времени.

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

Настройка

Для нашего приложения нам понадобятся следующие файлы:

- index.html

- style.css

- app.js

index.html будет содержать HTML разметку

style.css предназначен для хранения основных стилей. В данном пример мы будем активно использовать Bootstrap.

app.js будет содержать код, написанный на AngularJS. Именно тут мы подключимся к Firebase и будем получать данные.

Давайте приступим к созданию разметки.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Angular Scheduling</title>

    <!-- CSS -->
    <!-- load Bootstrap and custom style.css -->
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootswatch/3.3.0/journal/bootstrap.min.css">
    <link rel="stylesheet" href="style.css">

    <!-- JS -->
    <!-- load Angular, Firebase, Firebase Angular Library, and custom app.js -->
    <script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.0/angular.min.js"></script>
    <script src="https://cdn.firebase.com/js/client/1.1.1/firebase.js"></script>
    <script src="https://cdn.firebase.com/libs/angularfire/0.8.0/angularfire.min.js"></script>
    <script src="app.js"></script>
</head>
<body>
<div class="container" ng-app="scheduleApp" ng-controller="mainController">

  <div class="page-header text-center">
    <h1>Schedule City</h1>
  </div>

  <!-- were doing one day with 1 time slot for simplicity -->
  <!-- we'll use angular's ng-repeat in a bit to get the other days and times -->
  <div class="row times">

    <div class="col-xs-4 text-center">

      <h2>Monday</h2>

      <div class="time-slot">
        <input type="checkbox" id="monday-time">
        <label for="monday-time">9:00am</label>
      </div>
    </div>

  </div>

  <p class="text-center">
    <a href="#" class="btn btn-primary">Reset</a>
  </p>

</div>
</body>
</html>

Для удобства мы прячем input, вместо него делаем кликабельным элемент label. Для корректной работы скрипта, убедимся что каждый элемент label должен содержать атрибут id с указанием идентификатора элемента input.

CSS

Теперь открываем style.css и приступаем к стилизации.

/* checkbox - слот с временем */
.time-slot               {  }

/* прячем checkbox - label остаётся */
.time-slot input     {
  display:none;
}

/* стилизация для label-ов */
.time-slot label     {
  padding:10px 20px;
  color:#FFF;
  cursor:pointer;
  background:#EEE;
  border-radius:5px;
  transition:0.3s ease all;
}

/* если label был выбран */
.time-slot input:checked ~ label {
  background:#f2dede;
  cursor:not-allowed;
  animation:flashBooked 0.5s ease;
}

/* если label не выбран */
.time-slot input:not(:checked) ~ label {
  background:#6AB074;
  animation:flashAvailable 0.5s ease;
}

/* анимация окраски слота в красный цвет */
@keyframes flashBooked {
  0%, 100%  { background:#f2dede; transform:scale(1); }
  50%       { background:#F99090; transform:scale(1.5); }
}

/* анимация окраски слота в зелёный цвет */
@keyframes flashAvailable {
  0%, 100%  { background:#6AB074; transform:scale(1); }
  50%       { background:rgb(119, 218, 78); transform:scale(1.5); }
}

Браузерные префиксы: для упрощения, в данном листинге, мы не использовали браузерные префиксы -moz- или -webkit-.

Теперь у нас есть основа приложения. На данном этапе оно не очень динамично поскольку не взаимодействует с реальными данными. Давайте подключим Angular и Firebase для получения реальных данных.

JS (AngularJS)

Теперь мы начнём оживлять нашу страницу при помощи Angular шаг за шагом, а затем интегрируем наше приложение и Firebase.

// создаём модуль и передаём firebase
angular.module('scheduleApp', ['firebase'])

// создаём основной контроллер и передаём доступ к firebase
.controller('mainController', function($scope, $firebase) {

 // основной код приложения

});

Теперь можем взаимодействовать с Firebase.

Подключение и использование Firebase

Для начала нам нужно завести аккаунт на Firebase. После этого, нужно выбрать ценовой пакет: выбираем Hacker Plan, который является бесплатным.

URL вида (burning-torch-4263.firebaseIO.com) будет вашим персональным адресом приложения. Перейдя по нему вы можете попасть в панель управления.

Теперь когда у нас есть URL приложения, можем подключиться к нему из нашего Angular кода.

Создание подключения

Создать подключение к Firebase из Angular очень просто. У данного сервиса есть специальная библиотека для Angular под названием AngularFire. Мы уже добавили её в наш проект, подключив через HTML и передав в Angular приложение.

// создаём модуль и передаём firebase
angular.module('scheduleApp', ['firebase'])

// создаём основной контроллер и передаём доступ к firebase
.controller('mainController', function($scope, $firebase) {

 // подключаемся к firebase
  var ref = new Firebase("https://burning-torch-4263.firebaseio.com/days");
  var fb = $firebase(ref);

});

Для подключения к сервису этого вполне хватит! Заметьте, что в конце адреса мы добавили слово days. Таким образом вы можете передать дополнительную информацию. Теперь, всё что мы переправим, будет сохранено в объекте days в нашей базе данных.

Давайте введём тестовые данные и создадим кнопку сброса.

Настройка данных

Используя созданный нами объект fb, мы можем извлечь информацию из сервиса. В документации Firebas есть вся необходимая информация, демонстрирующая процесс отправки и приём данных. Давайте создадим данные для 2х дней (Понедельник и Вторник), заполнив по 2 ячейки.

Мы создадим Angular функцию для создания данных и прикрутим к ней кнопку Reset.

// создаём модуль и передаём firebase
angular.module('scheduleApp', ['firebase'])

// создаём основной контроллер и передаём доступ к firebase
.controller('mainController', function($scope, $firebase) {

 // подключаемся к firebase
  var ref = new Firebase("https://burning-torch-4263.firebaseio.com/days");
  var fb = $firebase(ref);

 // функция определения изначальных данных
  $scope.reset = function() {

    fb.$set({
      monday: {
        name: 'Monday',
        slots: {
          0900: {
            time: '9:00am',
            booked: false
          },
          0110: {
            time: '11:00am',
            booked: false
          }
        }
      },
      tuesday: {
        name: 'Tuesday',
        slots: {
          0900: {
            time: '9:00am',
            booked: false
          },
          0110: {
            time: '11:00am',
            booked: false
          }
        }
      }
    });

  };

});

Связываем объекты monday и tuesday с секцией days в нашей базе данных.

Теперь добавим HTML код кнопки сброса информации.

<p class="text-center">
    <a href="#" class="btn btn-primary" ng-click="reset()">Reset</a>
  </p>

В атрибуте указываем функцию сброса информации. Кликните на кнопку Reset и посмотрите на данные в панели Firebase.

Теперь, когда у нас есть информация, её нужно отобразить в самом приложении. Во-первых, нам необходимо связать данные, пришедшие от Firebase с объектом Angular. Существует два основных способа синхронизации информации: третий способ связки данных и пуш массива.

В этом видео нам необходимо мгновенное отображение синхронизированных данных, так что воспользуемся третьим способом связки данных. Вариант с массивом используется при других условиях. В этом случае, все сообщения синхронизируются при клике по кнопке “Send”.

Итак, мы будем использовать третий вариант синхронизации данных. Для начала синхронизируем информацию, полученную из базы данных и переменной в Angular.

Синхронизация объектов

Для синхронизации объектов можем сделать следующее:

// создаём модуль и передаём firebase
angular.module('scheduleApp', ['firebase'])

// создаём основной контроллер и передаём доступ к firebase
.controller('mainController', function($scope, $firebase) {

 // подключаемся к firebase
  var ref = new Firebase("https://burning-torch-4263.firebaseio.com/days");
  var fb = $firebase(ref);

 // синхронизация объекта
  var syncObject = fb.$asObject();

});

Теперь вся информация будет храниться в переменной syncObject в формате JSON.

Для завершения процесса необходимо вызвать функцию $bindTo.

Третий способ синхронизации данных

Полный код получения информации из базы данных и передачи в переменную $scope.

// создаём модуль и передаём firebase
angular.module('scheduleApp', ['firebase'])

// создаём основной контроллер и передаём доступ к firebase
.controller('mainController', function($scope, $firebase) {

 // подключаемся к firebase
  var ref = new Firebase("https://burning-torch-4263.firebaseio.com/days");
  var fb = $firebase(ref);

 // синхронизация объекта
  var syncObject = fb.$asObject();

 // синхронизация данных
  syncObject.$bindTo($scope, 'days');

});

Что действительно круто, так это то, что это весь код, который нам нужен для извлечения данных из Firebase и синхронизацией со всеми устройствами, подключёнными к странице.

Теперь наши данные обновляются в режиме реального времени!

Всё бы хорошо, но нам осталось извлечь информацию из переменной $scope и отобразить на странице.

Отправляемся в HTML файл и пишем {{ days }} в результате чего получим информацию, которую до этого определили в функции reset().

Воспользуемся циклом ng-repeat для прокрутки по полям объекта и отображения наших слотов.

Динамическое отображение дней и временных слотов

В файле index.html где отображаются дни и слоты времени, обновим информацию, получив её из объекта $scope.

Обновлённый HTML:

<div class="row times">

  <div class="col-xs-4 text-center" ng-repeat="day in days">

    <h2>{{ day.name }}</h2>

    <div class="time-slot" ng-repeat="slot in day.slots">

      <input type="checkbox" id="{{ day.name }}-{{ $index }}" ng-model="slot.booked" ng-disabled="slot.booked">

      <label for="{{ day.name }}-{{ $index }}">{{ slot.time }}<br>
        <span ng-if="slot.booked">Booked</span>
        <span ng-if="!slot.booked">Available</span>
      </label>

    </div>
  </div>

</div>

Проходимся в цикле по полям объекта $scope.days. Благодаря дополнительному ng-repeat, мы так же перебираем поля каждого дня (временные слоты).

Так же настраиваем чекбокс для того чтобы в ng-model обновить значение с false на true, при клике по слоту.

Для отключения того или иного слота мы воспользуемся ng-disabled, после того как пользователь забронировал время.

Синхронизация временных слотов

Вот тут-то и происходит волшебство: всё работает! В результате связки данных, при клике по временному слоту, то это в тот же момент отобразится на состоянии базы в Firebase!

Заключение

Приложения с поддержкой режима реального времени становятся всё более известны, a сервис Firebase это прекрасный инструмент для реализации подобного функционала. За бэк-энд часть отвечает Firebase, а вам остаётся заняться только фронт-эндом.

Firebase - классный сервис и каждому разработчику следует познакомиться с ним и постараться создать что-то клёвое.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: http://scotch.io/tutorials/javascript/build-a-real-time-scheduling-app-using-angularjs-and-firebase
Перевел: Станислав Протасевич
Урок создан: 8 Декабря 2014
Просмотров: 26995
Правила перепечатки


5 последних уроков рубрики "jQuery"

^ Наверх ^