jComponent - #Часть 1, Подключение, DataBinding

Javascript, jComponent 04 октября 2019 2 мин. 2062


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


Подключение

Библиотека состоит из нескольких частей:

  • jComponent - ядро
  • Helpers - содержат String, Date, Number, Array прототипы и многое другое
  • Tangular - мини шаблонизатор, если вы используете компоненты, шаблонизатор должен быть обязательно включен
  • jRouting - для создания маршрутизации на стороне клиента, HTML 5 routing с поддержкой History API

Библиотеку можно подключить разными способами:

CDN

https://cdn.componentator.com/spa.min@18.js
https://cdn.componentator.com/spa.min@18.css

spa.min@18.css - эта библиотека CSS содержит:

  • Bootstrap Grid System
  • Bootstrap tables
  • Font-Awesome 5 Free
  • Предопределенные стили

Пример подключения библиотеки:

<!-- jQuery + jComponent + Tangular + jRouting + Helpers -->
<link rel="stylesheet" href="https://cdn.componentator.com/spa.min@18.css" />
<script src="https://cdn.componentator.com/spa.min@18.js"></script>

Репозитарий

Для начала скачать или клонировать библиотеку из репозитария https://github.com/totaljs/jComponent. В архиве будут содержаться несколько файлов.

Имя файла Содержит
jc.min.js jComponent + Helpers
jcta.min.js jComponent + Tangular + Helpers
jctajr.min.js jComponent + Tangular + jRouting + Helpers
spa.min.js jQuery + jComponent + Tangular + jRouting + Helpers
spa.min.css Bootstrap Grid System + Font-Awesome

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

<link rel="stylesheet" href="vendor/bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="vendor/font-awesome/font-awesome.min.css" />
<script src="vendor/jquery/jquery-2.2.4.min.js"></script>
<script src="vendor/bootstrap/bootstrap.min.js"></script>
<script src="vendor/jc/jcta.min.js"></script>
<!-- js исходники компонент -->
<script src="vendor/jc/ui.js"></script>
<!-- css стили для компонент -->
<link rel="stylesheet" href="vendor/ui.css" />

Так же можно настроить сборку фронтенда и объединить все javascript и css в отдельные файлы. Таким образом мы уменьшим размер файлов, увеличим скорость отдачи необходимых ресурсов клиенту. Для этого Вы можете воспользоваться системами сборок типа Gulp или Grunt. В итоге подключение может быть таким:

<!-- Bootstrap+Font Awesome+ui -->
<link rel="stylesheet" href="app.min.css" />
<!-- Bootstrap+jQuery+jComponent+tAngular+ui -->
<script src="app.min.js"></script>

Data Binding (Связывание данных)

Cвязывание данных (data-binding) — это действительно важно, так как позволяет реализовать постоянную синхронизацию JS моделей с представлением, избежать массового дублирования кода, отвечающего за его обновления, и сделать приложение удобнее.

Схема Data Binding

В библиотеке jComponent для использования простого связывания нужно использовать следующую декларацию:

<div data-bind="path.to.property__command1:exp__command2:exp__commandN:exp"></div>

При изменении в JS переменной path.to.property автоматически произойдет изменения в представлении, при этом результат будет приведен соответствии с модификаторами command1:exp__command2:exp__commandN:exp. Проще все это разобрать и показать на основе примеров, которые приведены ниже.


Пример 1

Простое связывание. Представление меняется при изменении модели. Будем использовать следующую модель:

var obj = {'name': '', 'val': 10};

В HTML добавим теги с декларацией:

<!--отображаем значение из переменной obj.name и добавляем класс .bold -->
<p>Привет <span data-bind='obj.name__text:value__class:bold'><span></p>
<!--отображаем значение из переменной obj.val, если значение > 100, если < 100, то скрываем -->
<p>Значение: <span data-bind="obj.val__html:value__invisible:value > 100"></span></p>

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

 //изменение 1
 setTimeout(()=>{
    SET('obj.name', 'мир!');
 }, 1000)
 //изменение 2
 setTimeout(()=>{
    SET('obj.name', 'мирный мир!');
    SET('obj.val',  50);
 }, 2000)
 //изменение 3
 setTimeout(()=>{
    obj.name = 'мирный миру мир!';
    obj.val = 70;
    //обновляем модель
    UPDATE('obj');
 }, 3000)
 //изменение 4
 setTimeout(()=>{
    SET('obj.val',  120);
 }, 4000)
Метод: SET()

Метод устанавливает новое значение в соответствии с путем.

 SET(path, value, [type/delay], [reset]);
// @path {String}
// @value {Object}
// @type/delay {String/Number} Optional, number > 10 will be used as a delay
// @reset {Boolean} Optional, default: false
Метод: UPDATE()

Метод обновляет все компоненты в соответствии с путем.

 UPD(path, [type/delay], [reset]);
// or alias UPDATE()
// @path {String}
// @type/delay {String/Number} Optional, "value > 10" will be used as delay
// @reset {Boolean} Optional, default: false

Пример 2

Использование шаблона для отображение свойств объекта, а также форматируем числа при отображении. В HTML разместим следующий код:

<div data-bind="obj1__template">
   <script type="text/html">
      <div>Название: <b>{{ value.name }}</b></div>
      <div>Стоимость: <i>{{ value.price | format(2) }}<i></div>        
  </script>
</div>

Изменим модель через определенный интервал времени и сразу же последуют изменения в представлении.

 setTimeout(()=>{
    SET('obj1',  {'name': 'Комбинезон', 'price': 181.1523});
 }, 1000)

Пример 3

Использование шаблона для отображения свойств объектов из массива. Все изменения будут моментально отображены в представлении. Для этого в HTML разместим следующий код:

<div data-bind="arr__vbindarray">
  <script type="text/html">
    <!-- b говорит о том, что вывод будет сделан в соответвующий тег <b></b>-->
    <div data-bind=".name__html b">Имя услуги: <b></b></div>
    <p data-bind=".description__html"></p>
    <span>----------</span>
  </script>
</div>

Изменим модель через определенный интервал времени.

 setTimeout(()=>{
    arr = [{'name': 'Автомойка', 'description': 'Самый лучший сервис - автомойка'},
           {'name': 'Автосервис', 'description': 'Самый лучший сервис - автосервис'}];
   UPDATE('arr');
 }, 1000)

Пример 4

Используем анимацию в представлении, а также отображаем изображения. Для этого в HTML разместим следующий код:

<!-- css стили для создания анимации -->
<style>
  .fadeout {
    -webkit-transition: opacity 2s ease-in-out;
    -moz-transition: opacity 2s ease-in-out;
    -ms-transition: opacity 2s ease-in-out;
    -o-transition: opacity 2s ease-in-out;
    opacity: 0;
  }
  .fadein {
    -webkit-transition: opacity 2s ease-in-out;
    -moz-transition: opacity 2s ease-in-out;
    -ms-transition: opacity 2s ease-in-out;
    -o-transition: opacity 2s ease-in-out;
    opacity: 1;
  }
</style>

 <!-- если значение > 100 скроем с использованием класса .fadeout,  
 если значение < 100 отобразим с использованием класса .fadein -->
<div data-bind="obj3.val__.fadeout:value > 100__.fadein:value < 100">Анимация, скрытие элемента если значение будет больше 100 </div>
<!-- если переменная obj4.url != undefined, то отобразим изображение -->
<img data-bind="obj4.url__.fadeout:!value__.fadein:value__src:value" style='width:400px'>

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

 var obj3 = {};
 setTimeout(()=>{
    SET('obj3.val',  120);
 }, 1000)

 setTimeout(()=>{
    SET('obj3.val',  50);
 }, 2000)

 setTimeout(()=>{
    SET('obj4.url',  'https://bufferwall.com/download/B20190831T000000158.jpg');
 }, 3000)

Пример 5

Сделаем витрину с товарами. При покупке товара, будем отображать количество товаров в корзине и общую сумму. При нажатии на кнопку "Купить" будет обновлять количество и итоговую сумму товаров в корзине. В HTML разместим следующий код:

<div data-bind="obj5__vbindarray">
  <script type="text/html">
    <div data-bind=".name__html b">Название: <b></b></div>
    <p>Цена: <span data-bind=".price__html__format:1"></span> руб.</p>
    <!-- при клике на кнопку будет вызываться функция link_buy-->
<button data-bind="null__click:link_buy">Купить</button>
    <div>----------</div>
  </script>
</div>
<p>Стоимость товаров: <span data-bind='obj5_basket.bal__text:value__format:2'></span> руб., Кол-во: <span data-bind='obj5_basket.cnt__text:value'></span></p>
<!-- при клике на кнопку будет вызываться функция clear_buy-->
<button data-bind="price__click:clear_buy">Очистить корзину</button>

Разместим код js со всеми обработчиками.

 var obj5 = [{'name': 'Продукт 1', 'price': 2.75}, {'name': 'Продукт 2', 'price': 3.76}];
 var obj5_basket = {'bal': 0, 'cnt': 0};
 //обработка клика при покупке товара
 function link_buy(element, event, value, path) {
    //найдем индекс товара в массиве
    var index = $(element).data('index');
    //обновим корзину с товарами
    obj5_basket.bal += obj5[index]['price'];
    obj5_basket.cnt += 1;
    UPDATE('obj5_basket');  
 }
//очистить корзину
 function clear_buy(element, event, value, path) { 
    SET('obj5_basket', {'bal': 0, 'cnt': 0});   
 }

Работа всех примеров показана ниже:


Ссылки:

Категории