Advertisement
  1. Code
  2. Web Development

Використання фабрики віджетів jQuery UI

by
Difficulty:IntermediateLength:LongLanguages:

Ukrainian (українська мова) translation by AlexBioJS (you can also view the original English article)

Довгий час створення користувальницьких засобів керування в jQuery відбувалося тільки за допомогою розширення простору імен $.fn (* додавання методу до jQuery.prototype. Тут і надалі примітка перекладача). Цей спосіб працює добре для створення простих віджетів (* у віконній системі - стандартний, повторно використовуваний графічний елемент інтерфейсу користувача (кнопка, повзунок, вікно редагування тощо).   користувацькі засоби керування (user controls) в Apple Computers), проте якщо ви переходите до створення віджетів зі зберіганням стану (* вони мають життєвий цикл, в них підтримується стан і вони реагують на зміни. Для них необхідно написати багато коду для їх ініціалізації та керування станом; на відміну від них віджети без зберігання стану просто виконують певні дії, наприклад, якщо ви встановлюєте текст елемента за допомогою .text( "hello" ), то при цьому не було етапу налаштування і результат завжди той самий), то використовувати його вже стає обтяжливо. Для підтримки розробників при створенні віджетів команда jQuery UI розробила фабрику віджетів (Widget Factory), що полегшує процес їх розроблення.

Фабрика віджетів – частина jQuery UI Core – надає об'єктно-орієнтований спосіб реалізації стадій життєвого циклу віджета. У цьому циклі виділяють наступні стадії:

  • створення та зруйнування віджета
  • зміна опцій віджета
  • використання викликів  «super» для дочірніх віджетів
  • оповіщення про події

Давайте ознайомимся з цим API на прикладі створення простого віджета кульової діаграми (* різновид гістограми, стовпчаста діаграма).


Віджет кульової діаграми

До того, як створити цей віджет, давайте розберемося з його складом. Кульова діаграма – різновид гістограми (* стовпчастої діаграми); поняття ввів Stephen Few (* Стівен Ф'ю).

Bullet ChartBullet ChartBullet Chart

Ця діаграма складається зі смужок та міток, що накладаються одна на одну, щоб відобразити відносну ефективність. На ній є шкала кількісних значень для відображення області значень. Завдяки такому сумісному використанню смужок та міток можна повідомити більше інформації без шкоди для читабельності. У легенді роз'яснюється, які дані яким кольором, штрихуванням чи видом лінії представлені.

Код HTML для цієї діаграми наводиться нижче:

Наш віджет, що у нас буде називатися jquery.bulletchart, буде створювати цей HTML, використовуючи надані дані. З готовим віджетом можна ознайомитися на сторінці з демоверсією, яку ви можете скачати з GitHub. Виклик методу для створення віджета повинен буде виглядати наступним чином:

Всі значення задаються у процентах. Опцією size можна скористатися, коли ви хочете відобразити декілька кульових діаграм відносного розміру одна за одною. Опція ticks використовується для нанесення відміток на шкалу. Мітки та смужки задаються у вигляді масиву літералів об'єктів із властивостями title, value та css.


Створюємо віджет

Тепер, коли ми розібралися зі структурою віджета, давайте розпочнемо його створення. Віджет створюється за допомогою виклику $.widget(), аргументами якої виступають ім'я віджета та об'єкт, у якому містяться методи його екземпляру. Точний API виглядає наступним чином:

jQuery.widget(name[, base], prototype)

Зараз ми будемо працювати тільки з першим та третім аргументами. Базова заглушка для нашого віджета виглядає наступним чином:

Рекомендується, щоб у першому аргументі завжди містився простір імен перед іменем віджета. У нашому випадку ми використовуємо 'nt.bulletchart'. Всі віджети jQuery UI належать до простору імен 'ui'. Хоча ми й додаємо наш віджет до певного простору імен, у виклику, що ми використовуємо для створення віджета, для елемента простір імен відсутній. Тому, щоб створити кульову діаграму, ми будемо просто викликати $('#elem').bulletchart().

Властивості екземпляра задаються в об'єкті, що йде за іменем віджета. Умовно вважається, що всі приватні методи віджета повинні мати префікс '_'. У літералі об'єкта необхідно задати певні властивості: options, _create, _destroy та _setOption.

  • options: це – опції за налаштуванням для віджета.
  • _create: фабрика виджетів викликає цей метод при першій ініціалізації віджета.  Цей метод використовується для створення первісного DOM та приєднання яких-небудь обробників подій.
  • _init: після виклику _create фабрика викликає _init. Цей метод використовується для скидання віджета до вихідного стану. Тільки-но віджет створено, скинути віджет можна також за допомогою виклику конструктора без аргументів, наприклад, після виклику $.bulletchart() також відбудеться скидання віджета. У цій функції зсередини викликається _init.
  • _setOption: викликається, коли ви встановлюєте опцію для віджета, наприклад: $('#elem').bulletchart('option', 'size', 100). Пізніше ми розглянемо інші способи задання опцій для віджета.

Створюємо первісний DOM за допомогою _create

Наш віджет реалізується в методі  _create. Саме тут ми створюємо базову структуру діаграми. З функцією _create ви можете ознайомитися нижче. Ви помітите, що найважливіше, що тут відбувається, – це створення контейнера верхнього рівня. Фактична робота по створенню DOM для смужок, відміток та міток відбувається в методі _setOption. Це може здатися не зовсім інтуїтивно-зрозумілим спочатку, проте для цього є поважна причина.

Зверніть увагу, що значення смужок, відміток та міток також можуть бути змінені шляхом задання опцій для віджета. Якщо би ми розмістили код для його створення всередині _create, то ми би продублювали себе в _setOption. Завдяки переміщенню коду до _setOption та виклику його з _create ми видаляємо дублювання і також централізуємо створення віджета.

Крім того в коді вище показано, як ще можна задавати значення опцій для віджета. За допомогою методу _setOptions (зверніть увагу на множину) ви можете задати значення декількох опцій за один раз. Фабрика при цьому буде здійснювати зсередини окремі виклики _setOption для кожної опції.

Метод _setOption

Для нашої програми метод _setOption – робочий коник. Завдяки ньому здійснюється створення міток, смужок та відміток та зміна значень цих властивостей. При цьому відбувається видалення будь-яких елементів та їх відтворення на основі нового значення.

Метод _setOption приймає в якості параметрів ключ опції та значення. Ключ – це ім'я опції, яке повинно відповідати одному з ключів опцій за налаштуванням. Наприклад, для того, щоб змінити смужки віджета ви могли би здійснити наступний виклик:

Метод _setOption для нашої кульової діаграми виглядає наступним чином:

Тут ми створюємо простий набір імен опцій та їх відповідних функцій.  При цьому ми працюємо тільки з дозволеними опціями та пропускаємо решту. Також тут відбувається ще два моменти: виклик _super() та генерування події, що сповіщає про зміну опції. Ми розглянемо їх пізніше в цьому посібнику.

Для кожної опції, що змінює DOM, ми викликаємо певний допоміжний метод. Допоміжні методи: createBars, createMarkers та createTickBar визначені ззовні від властивостей екземпляра віджета. Це так, оскільки вони однакові для всіх віджетів та повинні бути створені окремо для кожного екземпляру віджета.

Значення всіх цих функцій задаються в процентах. Завдяки цьому гарантується, що діаграма змінюється належним чином при зміні розмірів елемента, в якому вона знаходиться.

Опції за налаштуванням

Якщо ми не вказуємо будь-які опції при створенні віджета, то у гру вступають опції за налаштуванням. За це відповідає властивість options. Для нашої діаграми опції за налаштуванням виглядають наступним чином:

Ми задаємо розмір (100%) та відмітки (кожні 10% діаграми), а смужки та мітки відсутні. На основі цих значень наша діаграма повинна виглядати наступним чином:

Default Bullet ChartDefault Bullet ChartDefault Bullet Chart

Поки що ми бачили, як створювати віджет за допомогою _create та оновлювати його за допомогою _setOption. Є ще один метод життєвого циклу, що буде викликатися при зруйнуванні віджета. Мова йде про метод _destroy. При виклику $('#elem').bulletchart('destroy') фабрика віджетів зсередини викликає _destroy для вашого екземпляра віджета. Віджет відповідає за видалення всього, що було винесено їм до DOM. Це можуть бути класи та інші елементи DOM, що були додані у методі _create. Також його можна використовувати для відв'язування яких-небудь обробників подій. Метод _destroy повинен працювати протилежно методу _create.

Для віджета нашої діаграми метод _destroy доволі простий:


Створення похідного класу, події та ще дечого

Ми реалізували майже всі можливості нашої діаграми: окрім останньої – легенди. Вона доволі важлива, оскільки підкаже, що означають мітки та смужки віджета. У цьому розділі ми додамо легенду поряд з діаграмою.

Замість того, щоб додати цю можливість напряму до віджета bulletchart, ми створимо підклас,  bulletchart2, в  якому буде підтримка легенди. В процесі його створення ми також ознайомимося з деякими цікавими особливостями наслідування у фабриці віджетів.

Додавання легенди

Chart with LegendChart with LegendChart with Legend

У фабриці віджетів є підтримка наслідування віджетів для створення більш спеціалізованих версій. Раніше у посібнику ми бачили API для $.widget() з трьома аргументами:

jQuery.widget(name[, base], prototype)

Завдяки цьому аргументу ми можемо вибрати базовий клас (* клас, із якого здійснюється спадкування підкласами) для нашого віджета. Наш віджет bulletchart2, що є похідним від bulletchart, буде мати наступну сигнатуру (* ім'я та список параметрів):

Тут ватро звернути увагу на наступні моменти:

  • Ми знову упереджаємо ім'я нашого віджета назвою простору імен: nt.bulletchart2.
  • Фабрика віджетів автоматично включає цей віджет до простору імен $.nt namespace. Тому для посилання на наш попередній віджет ми використовуємо $.nt.bulletchart. Подібним чином, якщо би ми створили похідний клас від  стандартних віджетів jQuery UI, то ми би послалися на них за допомогою $.ui.widget-name.
  • З властивістю widgetEventPrefix ми зустрічаємося вперше. Ми до неї ще повернемося, коли будемо обговорювати події. Решта властивостей екземпляра повинна бути вам вже добре знайома.

Оскільки цього разу ми додаємо більше значень елементів DOM (з урахування легенди), то нам необхідно буде переписати метод _create. Це також означає, що нам необхідно буде переписати й метод _destroy, щоб бути послідовними (* логічно закономірними).

Тут ми маємо той же шаблон, що і в методі _create раніше. Ми створюємо контейнер для легенди і потім викликаємо _setOption для створення решти компонентів легенди. Оскільки ми перезаписуємо _create, то нам необхідно впевнитися, що викликали _create базового класу. Ми це робимо за допомогою _super. Подібним чином ми викликаємо _super для _destroy.

Тепер ви можете задуматися: яким чином віджет знає, який саме метод _super викликати, якщо в ньому викликається простий невизначений _super? Розгадка полягає в суті фабрики віджетів. При наслідуванні віджета фабрика встановлює різноманітні значення для _super в залежності від функції екземпляра. Тому, коли ви викликаєте _super із методу вашого екземпляра, то при цьому ви завжди посилаєтеся на коректний метод _super.

Сповіщення про події

Оскільки у кульовій діаграмі є підтримка змін відміток та смужок, то легенда повинна бути синхронізована з цими змінами. Також ми реалізуємо переключення видимості відміток та смужок при клацанні елементів легенди. Це буде корисним, якщо у вас є декілька відміток та смужок. Ховаючи декілька елементів, ви побачите решту більш розбірливо.

Для реалізації синхронізації легенди зі змінами, що відбуваються з відмітками та смужками, віджет bulletchart2 повинен прослуховувати будь-які зміни, що відбуваються з цими властивостями. Базовий віджет bulletchart вже генерує спеціальну подію кожного разу, коли змінюються його опції. Нижче наведено відповідний фрагмент коду з базового віджета:

Кожного разу при заданні опції генерується подія setOption. У цих подіях містяться попереднє та наступне значення для опції, яку було змінено.

Завдяки прослуховуванню цієї події у дочірньому віджеті ви зможете визначати, коли відбуваються зміни з відмітками та смужками.  Віджет bulletchart2 підписується на цю подію у своєму методі _create. Підписування на події, що генеруються віджетом, здійснюються за допомогою виклику this.element.on().  this.element вказує на елемент jQuery, для якого було ініційовано віджет. Оскільки подію буде згенеровано при виконанні дій із ним, підписування на подію необхідно виконати для нього.

Зверніть увагу на ім'я події, на яку ми підписуємося: 'bulletchart:setoption'. Згідно з правилами, фабрика віджетів приєднує спеціальний префікс для подій, згенерованих при виконанні дій з віджетом. За налаштуванням цим префіксом є ім'я віджета, проте його можна легко замінити за допомогою властивості widgetEventPrefix. У базовому віджеті відбувається його заміна на 'bulletchart:'.

Також нам необхідно підписатися на події 'click', що генеруються при виконанні дій з елементами легенди, для приховання/показу відповідної відмітки/смужки. Ми виконаємо це за допомогою методу _on. У якості параметра для обробника в цьому методі використовується event (* дані події). Контекст обробника (this) коректно відповідає екземпляру віджета. Ще одна угода при використанні _on полягає в тому, що фабрика віджетів автоматично відв'язує події при зруйнуванні віджета.


Додаткові поради

Також у фабриці віджетів є ще декілька чудових особливостей, про які вам варто знати.

Посилаємося на екземпляр віджета.

До цього часу ми бачили тільки один спосіб виклику методів віджета. Ми виконували його за допомогою $('#elem).bulletchart('method-name'). Але при цьому ми можемо викликати тільки публічні методи, наприклад: 'option', 'destroy', 'on', 'off'. Якщо ви хочете викликати ці методи напряму для екземпляра віджета, то є один спосіб. Фабрика віджетів приєднує екземпляр віджета до об'єкта data() елемента. Ви можете отримати цей екземпляр наступним чином:

Окрім цього, якщо ви хочете отримати набір усіх віджетів кульової діаграми на сторінці, то для цього також є селектор:

Деякі спеціальні методи

Є декілька спеціальних методів, про які вам варто знати (вони використовуються набагато рідше): _getCreateEventData() та _getCreateOptions(). Перший використовується для приєднання даних події для події  'create', що генерується після завершення виклику _create.

_getCreateOptions використовується для приєднання додаткових опцій за налаштуванням для віджета або перезаписування вже існуючих. Опції, задані користувачем, перезаписують опції, що повернулися цим методом, а останні перезаписують опції віджета за налаштуванням.


Резюме

Це тільки верхівка айсберга. Якщо ви хочете дізнатися більше, то посилань нижче буде цілком достатньо. Звісно ж, найкращим джерелом інформації завжди буде власне початковий код. Я би дуже радив вам ознайомитися з початковим кодом jquery.ui.widget на GitHub.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.