1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-qcobjects

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 190 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 04.03.2025 14:07 45c52c7

logo

GitHub лицензия Статус FOSSA Статус документации GitHub выпуск GitHub звезды npm версия apm: версия docker pulls Соглашение Contributor Covenant Лучшие практики CII

Станьте патроном

QCObjects — чтобы кодировать шикарно, чисто и быстро | Product Hunt# QCObjects

Добро пожаловать в QCObjects. Открытая платформа, которая позволяет опытным разработчикам создавать микросервисы и микросерверы в виде многоуровневой архитектуры. С помощью QCObjects можно также писать как для фронтенда, так и для бэкенда, используя общую синтаксическую конструкцию на чистом JavaScript. Это кросс-браузерное, кроссплатформенное и кросс-фрэйм решение.Установите его, создайте поле ввода или реализуйте функциональность навигации домой всего за один шаг.

QCObjects отмечен Британским Геральдом как самое передовое фреймворк для современного программирования сегодня.

Это основной справочный документ!

Репозиторий и README доступны по адресу https://qcobjects.dev.

Проверьте официальный сайт QCObjects по адресу https://qcobjects.com.

Этот проект следует Кодексу поведения Contributor Covenant. Участвуя в нем, вы обязаны придерживаться этого кодекса. Неприемлемое поведение можно сообщить по адресу info@quickcorp.cl.

Добровольные вклады приветствуются!

Вы можете внести свой вклад в QCObjects, следуя набору правил, изложенных в файле CONTRIBUTING.md.

Описание названия QCObjects (Не забудьте про Q)

Часто некоторые люди путают название QCObjects с CObjects (может быть, когда-нибудь это изменится...), но буква Q имеет важное значение: она означает быстрый! Полное название QCObjects расшифровывается как Быстрые компоненты и объекты, поэтому буквы Q, C, O пишутся заглавными.

Объясняющее видео QCObjects

Для тех, кто не хочет читать всё это сегодня, вот небольшое видео, которое объясняет, что такое QCObjects и что можно сделать с ним.Объясняющее видео QCObjects


Содержание<! -- TOC depthFrom:1 depthTo:3 withLinks:1 updateOnSave:1 orderedList:0 -->

  1. Вы должны вводить код на JavaScript для создания приложения на JavaScript.
  2. Каждый объект является экземпляром другого объекта.
  3. Каждый объект имеет определение.
  4. На стороне клиента любой объект может быть добавлен в DOM или Virtual-DOM без необходимости заново объявлять его определение.
  5. У каждого объекта есть тело.
  6. Класс должен служить основным определением объекта.
  7. Класс должен легко приводиться к типу объекта.
  8. Ваш код должен легко организовываться в пакеты.
  9. Ваш код должен позволять легко создавать чистую архитектуру вашего приложения.
  10. Компонент — это сущность, имеющая объектное представление и объявление тега. Содержимое компонента должно быть возможно заполнить как удаленно, так и локально. Как компонент является объектом, он также имеет своё тело, которое обычно представляет собой добавленный экземпляр DOM-элемента.
  11. Компонент можно прикрепить к DOM или отсоединить от него без влияния на его функциональность.
  12. Вызов сервиса может быть расширен для создания шаблона его функциональности.
  13. Вам следует иметь возможность импортировать пакет удалённо.
  14. Вам следует иметь возможность создавать шаблон вашего кода и контролировать ваши затраты на серверной стороне, не делая лишних вызовов к удалённым источникам.Вам не следует повторяться при создании таких контрольных механизмов.
  15. Вам следует иметь возможность программировать многокомпонентное приложение на одном языке или синтаксисе.
  16. Вам следует иметь возможность применять любую шаблонную структуру к компоненту, независимо от того, какой синтаксис или язык использовались для её написания.
  17. Если HTML-тег уже представлен экземпляром DOM-объекта, вам не следует повторно объявлять его определение для отображения содержимого.
  18. Главная страница HTML должна быть чистой. Но вы должны иметь возможность связывать то, что управляет поведением тега, без изменения синтаксиса HTML.
  19. Порядок выполнения вашего кода должен быть легко понятен и читаемым из самого кода, и процесс рендера каждого компонента должен иметь контроль выполнения на каждом уровне, который вам необходим.
  20. Для каждого компонента должен присутствовать слоистый шаблон (например, MVC или MVCC). Неважно, определяете ли вы каждый слой или нет.
  21. Поведение компонента не должно определяться его процессом рендера.
  22. Необходимо наличие стека компонентов, который разделяет DOM на подлежащее дерево прикреплённых элементов. Так теперь существует этот стек, и он называется "Стек вложенных компонентов QCObjects". Вы должны иметь возможность расширять экземпляр компонента.Но вы должны контролировать его динамическое поведение без влияния на его первоначальное объявление.
  23. Вы должны иметь возможность легко применять одновременные визуальные эффекты и анимации к любому экземпляру элемента DOM.
  24. Вы должны иметь возможность контролировать визуальные эффекты и анимации как с помощью CSS, так и с помощью JavaScript без влияния на производительность.
  25. Вы должны иметь возможность контролировать поведение вашего кода как внутри, так и вне коробки и успешно это делать. # Основные возможности- Встроенные и пользовательские шаблоны для Progressive Web Apps (PWA) и Accelerated Mobile Pages (AMP)
  • Революционные эффекты пользовательского интерфейса
  • Прорывные микросервисы серверной части
  • Простота дизайна вёрстки
  • Полностью рабочие командные средства (CLI)
  • Архитектура, основанная на объектах и компонентах
  • Передовой стек технологий с клиентской и серверной частей
  • Рекурсивное маршрутизация компонентов
  • Встроенное управление вложенными компонентами
  • Полностью интегрированный паттерн MVC (модель, представление, контроллер)
  • Динамические объекты данных
  • Основанный на концепциях многоуровневой архитектуры

Принятые возможности Progressive Web Apps (PWA)

Предотвращение блокировки рендера ресурсами

Чтобы предотвратить блокировку рендера ресурсами, QCObjects внедрил фабричную функцию Package.

Загрузка ресурсов по требованиюС использованием динамической архитектуры, основанной на компонентах, QCObjects отрисовывает каждый визуальный ресурс внутри компонента только при сборке самого компонента. Каждый компонент связан со структурой, называемой глобальным стеком компонентов (global.componentsStack), которая указывает на каждую экземплярную версию компонента и его подкомпоненты. При каждом перестроении компонента, визуальные ресурсы динамически перезагружаются наиболее эффективным образом, поэтому вам не придётся беспокоиться о сложном коде управления процессом загрузки ресурсов с помощью других фреймворков.## Ленивая загрузка изображений в компонентах (используйте lazy-src вместо атрибута src в теге img)

Начиная с версии 2.1.251, QCObjects предоставляет простой способ ленивой загрузки изображений, используя последний стандарт для браузеров.

<img src="img/preloader.svg" lazy-src="img/myrealimage.png"/>
```В приведённом выше коде используется заглушка (лёгкий вес) изображение для первой загрузки, а атрибут **lazy-src** используется для установки реального изображения, которое будет показано после завершения процесса ленивой загрузки. QCObjects загружает все объявленные теги **<img>** внутри компонента в режиме ленивой загрузки, если они имеют атрибут lazy-src, после перестроения или загрузки компонента. Также, QCObjects использует [API Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) (когда доступен), чтобы определить, является ли изображение lazy-src или src визуально полезным для отображения. Эффект ленивой загрузки заметен в первую очередь при первом запуске PWA. При последующих запусках скорость загрузки значительно увеличивается, что затрудняет восприятие глазом человека этих изменений. Однако эта функция существенно влияет на опыт пользователя при низкой скорости интернет-соединения или при работе с очень большими изображениями. Эта функция является частью рекомендованных функций для PWA, представленных на [веб-сайте разработчиков Mozilla](https://developer.mozilla.org/) в статье о прогрессивной загрузке. Вы можете прочитать эту статью [здесь](https://developer.mozilla.org).Если вы не хотите использовать ленивую загрузку для изображений, вы всегда можете продолжать использовать обычный способ загрузки, не добавляя атрибут **lazy-src** к тегу **<img>** и используя традиционный атрибут **src**.# Кроссбраузерный JavaScript-фреймворк для паттернов MVC
----------------------------------------

[QCObjects](https://qcobjects.dev) — это JavaScript-фреймворк, предназначенный для упрощения реализации паттернов MVC в чистом JavaScript. Вам не требуется использование TypeScript или какого-либо транспайлера для запуска [QCObjects](https://qcobjects.dev). Он работает непосредственно в браузере и использует чистый JavaScript без дополнительных зависимостей. Вы можете создавать свои компоненты, выраженные в реальных объектах JavaScript, или расширять нативные объекты DOM для использования по своему усмотрению. Также можно использовать [QCObjects](https://qcobjects.dev) вместе с CSS3-фреймворками, такими как [Foundation](https://foundation.zurb.com), [Bootstrap](https://getbootstrap.com) и мобильными JavaScript-фреймворками, такими как [PhoneGap](https://phonegap.com) и OnsenUI (https://onsen.io).

![скриншот](https://qcobjects.dev/doc/img/components.gif)

# Установите его, создайте поле ввода или добавьте функциональность "назад", всего за один шаг.

QCObjects можно установить на вашем компьютере; он приходит со средством командной строки и командами для создания шаблона вашего приложения всего за один шаг. Вернитесь домой без необходимости покидать страницу и создайте затенённое поле ввода всего за один шаг.

# Динамическая архитектура компонентов

![архитектура компонентов QCObjects](https://qcobjects.dev/doc/img/QCObjects-Components-Layout.gif)
[![Статус FOSSA](https://app.fossa.com/api/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects?ref=badge_shield)# Спецификация ECMA-262
--------------------------
См. [ECMAScript®  Yöntem Dili 2020 Spesifikasyonu](https://tc39.github.io/ecma262/#sec-intro) для справки

# Авторское право
-----------
Авторское право © Жан Макучака и [QuickCorp](https://quickcorp.org) <info@quickcorp.cl>

# Пример
--------------
## Пример PWA

Проверьте живой пример PWA на основе фронтенд-компонента QCObjects здесь:
[PWA QCObjects](https://newapp.qcobjects.dev/)

## Пример с использованием Foundation

Проверьте пример, использующий компоненты Foundation, здесь:
[Пример с использованием Foundation](https://github.com/QuickCorp/quickobjects_sample1foundation)

## Демонстрация интеграции с Materializecss

Просмотрите демонстрацию использования MaterializeCSS здесь:
[Демо с использованием Materializecss](https://qln.link)

## Демонстрация с использованием чистого CSS

Просмотрите демонстрацию использования чистого CSS здесь:
[Демо с использованием чистого CSS](https://github.com/QuickCorp/qcobjects_profile_browser)

## Пример использования QCObjects для манипулирования объектами канваса

Следующий код показывает, как QCObjects могут манипулировать объектами канваса непосредственно и внутри компонентов.

```html
<!DOCTYPE html>
<html>
    <head>
    	<title>Демо</title>
    	<script type="text/javascript" src="https://cdn.qcobjects.dev/QCObjects.js"></script>
    	<script type="text/javascript">
    		var canvas1, canvas2, canvas3, container;
        CONFIG.set('relativeImportPath','src/');
    		
    		/**
    		 * Основное импортирование.
    		 */
    		Import('cl.quickcorp', function() {
    		
    			/**
    			 * Супер контейнер MyOwnBody
    			 */
	    		Class('MyOwnBody', HTMLBodyElement, {
	    			customAttr: 'custom',
	    			body: document.body  // заменяет базовый элемент body
	    		});
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
    			
```md
# Журнал разработчика
--------------
Официальный [Журнал разработчика QCObjects](https://devblog.qcobjects.org/) размещен на [Hashnode](https://hashnode.com/). Журнал пишется лично Джоном Макучей, автором [QCObjects](https://qcobjects.com), который подробно объясняет лучшие практики и дает лучшие советы и хитрости использования самых продвинутых возможностей QCObjects.
```# Вилка проекта
--------------
Пожалуйста, сделайте вилку этого проекта или создайте ссылку на этот проект в вашем файле `README.md`. Прочтите файл `LICENSE.txt` перед использованием данного кода.

# Станьте спонсором
------------------
Если вы хотите стать спонсором этого замечательного проекта, вы можете сделать это [здесь](https://sponsorsignup.qcobjects.dev/).

# Посмотреть QCObjects SDK
----------------------------
Вы можете просмотреть [QCObjects SDK](https://sdk.qcobjects.dev/) и следовать примерам для создания своих собственных компонентов с уникальными функциями.

# Донат
--------------
Если вам понравился данный код, пожалуйста, [ДЕНОНИРУЙТЕ](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UUTDBUQHCS4PU&source=url)! 

[![PayPal](https://www.paypalobjects.com/webstatic/mktg/logo/AM_mc_vs_dc_ae.jpg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UUTDBUQHCS4PU&source=url)

[![Станьте покровителем на Patreon](https://c5.patreon.com/external/logo/become_a_patron_button.png)](https://www.patreon.com/join/qcobjects?)

# Установка
------------


## Использование QCObjects с Atom:

```shell
> apm install qcobjects-syntax

https://atom.io/packages/qcobjects-syntax

Использование QCObjects в Visual Studio Code:

Бейдж для установок расширения Visual Studio Code Quickcorp.QCObjects-vscode

Установка с помощью NPM:

> npm install qcobjects-cli -g && npm install qcobjects --save

screenshot2## Установка контейнерной среды для Docker:

docker pull -a quickcorp/qcobjects-playground && docker run -it --name qcobjects-playground --rm -it quickcorp/qcobjects-playground

screenshot3

Одношаговый скрипт установки для Ubuntu 18.x

ПРЕДУПРЕЖДЕНИЕ: Выполните это только в свежей/чистой/новой установке Ubuntu 18.x, не делайте этого в существующей производственной среде. Вас попросят предоставить права доступа от имени администратора (sudo).

curl -L https://cdn.qcobjects.dev/install_qcobjects_ubuntu18x.sh | sh

ПРЕДУПРЕЖДЕНИЕ: Я не несу ответственности за повреждение вашей инфраструктуры при использовании автоматизированного скрипта установки в небезопасной сети. Убедитесь, что все ваши репозитории и скрипты находятся под протоколом HTTPS с действительным сертификатом. Для получения лучших результатов рекомендую вам скачать скрипт, отредактировать его под свои специальные нужды и затем выполнить его на вашем компьютере локально.

Одношаговый скрипт установки для RHEL8

curl -L https://cdn.qcobjects.dev/install_qcobjects_rhel8.sh | sh

Одношаговый скрипт установки для Raspberry Pi Raspbian 9

su -c "curl -L https://cdn.qcobjects.dev/install_qcobjects_raspbian9.sh | sh" root

Одношаговый скрипт установки для macOS

Тестировалось на macOS Catalina 10.15.3

curl -L https://cdn.qcobjects.dev/install_qcobjects_macOS.sh | zsh

Установка и тестирование QCObjects на операционной системе Microsoft Windows1.- Установите последнюю версию NodeJS для Windows с этого сайта

2.- Из командной строки установите qcobjects-cli с помощью npm

npm i qcobjects-cli -g

3.- Создайте директорию для вашего проекта

md mynewproject && cd mynewproject

4.- Создайте новое Progressive Web Application QCObjects

qcobjects create mynewproject --pwa

screenshot

Установка QCObjects в многоблочном окружении

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

DigitalOcean One-Click Droplet

Если вы хотите забыть про apt-get и руководство по конфигурации, просто приступайте к развертыванию вашего проекта с помощью преднастроенной однонажатия приложения, включающей QCObjects CLI, QCObjects SDK и встроенного сервера QCObjects HTTP/2. Разверните его на виртуальной машине Droplet или кластере Kubernetes за 60 секунд или менее.

Создайте свой собственный QCObjects DigitalOcean Droplet здесь

AWS Amazon Machine Images (AMI)

Amazon Machine Image (AMI) предоставляет информацию, необходимую для запуска экземпляра. При запуске экземпляра вам следует указать AMI. Вы можете запустить несколько экземпляров из одного AMI, когда вам нужны несколько экземпляров с одинаковой конфигурацией. Вы также можете использовать различные AMI для запуска экземпляров, если вам нужны экземпляры с различной конфигурацией.AMI включает следующее:

  • Один или несколько EBS-снимков или, для AMI с базовым хранилищем экземпляра, шаблон корневого тома экземпляра (например, операционная система, сервер приложений и приложения).
  • Разрешения запуска, контролирующие, какие аккаунты AWS могут использовать AMI для запуска экземпляров.
  • Блок устройств, который указывает тома, которые должны быть подключены к экземпляру при запуске.

Начните создание своего AMI QCObjects здесь

Частное Amazon Machine Image (AMI) AWS PIB

Частное изображение позволяет вам создать новый AMI, установив программное обеспечение AWS Marketplace на изображение, выбранное из доступных AMI вашего аккаунта AWS. Это позволяет лучше соответствовать внутренним спецификациям безопасности, управления и соответствия требованиям. Как и стандартные AMI AWS Marketplace, каждый частный образ будет включать подписку для установленного продукта и будет иметь счет за использование программного обеспечения через AWS Marketplace.

Начните создание своего частного AMI QCObjects здесь

Использование кода версии разработки непосредственно в HTML5:

<script type="text/javascript" src="https://cdn.qcobjects.dev/QCObjects.js"></script>

Использование минифицированной версии кода из CDN jsDelivr

<script src="https://cdn.jsdelivr.net/npm/qcobjects/QCObjects.min.js"></script>
```## Использование последней не-минифицированной версии из CDN jsDelivr
```html
<script src="https://cdn.jsdelivr.net/npm/qcobjects/QCObjects.js"></script>

Использование CDN UNPKG

<script src="https://unpkg.com/qcobjects@latest/QCObjects.js"></script>

Использование CDNJS

<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/[VERSIЯ]/QCObjects.js"></script>

Где [VERSIЯ] — это соответствующая последняя версия с использованием цифровой нотации, пример: чтобы использовать версию 2.1.420:

<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/2.1.420/QCObjects.js"></script>

Вы не обязаны минифицировать QCObjects, но если вы всё же хотите использовать минифицированный код, вы можете сделать это:

<script src="https://cdnjs.cloudflare.com/ajax/libs/qcobjects/2.1.420/QCObjects.min.js"></script>

Ещё раз, замените 2.1.420 на номер желаемой версии.

Справочник


Основные понятия

Здесь представлены основные символы и концепции справочника QCObjects.

QC_Object

Основной тип всех элементов.

ComplexStorageCache

С помощью ComplexStorageCache можно управлять кэшем для любого объекта и сохранять его в локальном хранилище.

Пример использования:

var cache = new ComplexStorageCache({
    index: object.id, // Индекс объекта
    load: (cacheController) => {}, // Функция для выполнения при первом обращении
    alternate: (cacheController) => {} // Альтернативная функция для выполнения при повторном обращении
});

Пример:

var dataObject = {
    id: 1,
    prop1: 1,
    prop2: 2
};
```var cache = new ComplexStorageCache({
    index: dataObject.id,
    load: (cacheController) => {
      dataObject = {
              id: dataObject.id,
              prop1: dataObject.prop1 * 2, // Изменение значения свойства
              prop2: dataObject.prop2
            };
      return dataObject;
    },
    alternate: (cacheController) => {
      dataObject = cacheController.cache.getCached(dataObject.id); // Установка dataObject с кэшированным значением
      return;
    }
  });

// В следующий раз вы сможете получить объект из кэша
var dataObjectCopyFromCache = cache.getCached(dataObject.id);
console.log(dataObjectCopyFromCache); // Будет показывать те же самые значения объекта, что и dataObject
```### asyncLoad

Функция **asyncLoad** загружает код один раз в асинхронном режиме. Это полезно для обеспечения того, чтобы некоторые начальные процессы не повторяли свое выполнение и не загружались после чувствительного кода.

#### Пример использования:
```javascript
asyncLoad(() => {
  // мой код здесь
}, args);
// Где args — это массив аргументов, он может быть специальным объектом "arguments"

Пример:


let doSomething = (arg1, arg2) => {
  asyncLoad((arg1, arg2) => {
    console.log(arg1);
    console.log(arg2);
  }, arguments);
};

doSomething(1, 2); // Код функции doSomething будет выполнен один раз после очереди других асинхронных функций и до события готовности страницы.

Класс

Это НЕ определение класса ECMAScript 2015 (см. класс ECMAScript 2015 для справки).Класс — это специальная функция, которая помогает вам объявить класс более удобным и совместимым способом. Она работает кроссбраузерно, и я надеюсь, что ECMA когда-нибудь примет что-то подобное. Чтобы избежать путаницы с этим, QCObjects использует "Class", а не "class" (учтите CamelCase).#### Пример использования:

Class('MyClassName', MyClassDefinition);

Где MyClassDefinition — это объект с прототипом QCObjects.

Пример:

Class('MyClassName', InheritClass, {
  propertyName1: 0, // просто для декларации
  propertyName2: '',
  classMethod1: function() {
    // какой-то код здесь
    // учтите, что вы можете использовать объект "this"
    return this.propertyName1;
  },
  classMethod2: function() {
    // какой-то код здесь
    return this.propertyName2;
  }
});

var newObject = New(MyClassName, {
  propertyName1: 1, // это инициализирует значение в 1
  propertyName2: 'some value'
});
console.log(newObject.classMethod1()); // это покажет число 1
console.log(newObject.classMethod2()); // это покажет "some value"

Метод append

Это специальный метод, встроенный для упрощения работы при динамическом манипулировании DOM. Вы можете вставить даже компонент, объект QCObjects или элемент DOM внутрь другого элемента HTMLElement.

Пример использования:
[element].append([object or element]);

Пример:

// Это создаст класс QCObjects с названием "canvas", расширяющий HTMLCanvasElement с свойством customAttr со значением "custom"
Class('canvas', HTMLCanvasElement, {
  customAttr: 'custom'
});

// Это объявляет экземпляр canvas1 от класса canvas

let canvas1 = New(canvas, {
  ширина: 100,
  высота: 100
});

// Это прикрепляет объект canvas1 к телу документа

document.body.append(canvas1);

Метод super

Когда вы расширяете класс QCObjects из другого, вы можете использовать метод super для получения экземпляра из основной классовой определенной структуры.#### Пример использования:


_super_('ОсновнойКласс', 'ОсновнойМетод').call(this, параметры)
// где this — текущий экземпляр, а параметры — параметры метода

Пример:

Class('Сверхкласс', InheritClass, {
  свойство1: 0, // просто для декларации цели
  свойство2: '',
  метод1: function() {
    // некоторый код здесь
    // обратите внимание, что можно использовать объект "this"
    return this.свойство1;
  },
});

Class('ИмяМоегоКласса', Сверхкласс, {
  свойство1: 0, // просто для декларации цели
  свойство2: '',
  метод2: function() {
    // Следующая строка выполнит метод1 из сверхкласса
    // но использует текущий экземпляр ИмяМоегоКласса
    return _super_('Сверхкласс', 'метод1').call(this);
  }
});

var новыйОбъект = New(ИмяМоегоКласса, {
    свойство1: Yöntem1, // это инициализирует значение в 1
    свойство2: "некоторое значение"
});
console.log(новыйОбъект.метод2()); // это покажет число 1

New

Создает экземпляр объекта определенного класса QCObjects.

Пример использования:

let objectInstance = New(QCObjectsClassName, свойства);
// где свойства — это единственный объект со значениями свойств

Замечание: В объекте с свойствами вы можете использовать как одиночные значения, так и геттеры, но они будут выполняться один раз.

Пример:

Class('МойУникальныйКласс', Object);
let objectInstance = New(МойУникальныйКласс, {
  prop1: 1,
  get случайноечисло() { // этот геттер будет выполнен один раз
    return Math.random();
  }
});
```console.log(objectInstance.случайноечисло); // покажет случайное число
console.log(objectInstance.prop1); // покажет число 1

InheritClass

Одно общее использование определённого класса QCObjects.

ClassFactory

Используйте ClassFactory, чтобы получить экземпляр фабрики объявления класса QCObjects. Вы можете получить либо фабрику класса из пакета, либо из очереди стека классов. Чтобы получить ClassFactory из очереди классов, вы можете просто использовать имя класса непосредственно в коде.

Пример:

/* Когда вы объявляете MyClass с помощью Class(), он сразу же добавляется в очередь классов,
 * и вы можете получить фабрику, используя ClassFactory() или вызывая имя MyClass прямо в коде
 */
Class('MyClass', {
	a: 1
});
console.log(MyClass === ClassFactory('MyClass')); // будет показывать true
/* С другой стороны, ClassFactory() окажется полезной, когда вы определяете класс в пакете
 */
Package('org.quickcorp.package1', [
	Class('MyClass', {
		a: 1
	})
]);
console.log(MyClass === ClassFactory('MyClass')); // всё ещё покажет true
// Следующая строка также покажет true
console.log(MyClass === ClassFactory('org.quickcorp.package1.MyClass'));
``````javascript
/* An interesting point is the situation where you declared more than one class with the same name MyClass
 * in different packages but with different default property values and even different properties
 */
Package('org.quickcorp.package1', [
	Class('MyClass', {
		a: 1
	})
]);
Package('org.quickcorp.package2', [
	Class('MyClass', {
		a: 2,
		b: 1
	})
]);
// The last declaration of MyClass will be the one that survives in the queue of classes,
// so a reference to MyClass in the code will point to this class
console.log(MyClass === ClassFactory('MyClass')); // still shows true
```// В этом случае, как MyClass, определенный в org.quickcorp.package1, не будет таким же,
// как тот, который в org.quickcorp.package2, но MyClass в package2 — последний,
// следующая строка покажет false
console.log(MyClass === ClassFactory('org.quickcorp.package1.MyClass'));

// Следующая строка покажет true
console.log(MyClass === ClassFactory('org.quickcorp.package2.MyClass'));

// Следующая строка покажет false
console.log(ClassFactory('org.quickcorp.package1.MyClass') === ClassFactory('org.quickcorp.package2.MyClass'));

Вышеупомянутые примеры сделаны намеренно, чтобы объяснить и продемонстрировать, как область определения классов в QCObjects защищена и обрабатывается, что отражается в использовании ClassFactory.

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

// Когда вы обычно расширяете класс с помощью очереди класса, вы делаете следующее:
Class('МойРасширенныйКласс', МойНаследуемыйКласс, {
	расширеннаяПараметр1: 'значение параметра',
	расширеннаяПараметр2: 2
});
/* Но чтобы защититься от путаницы ссылками, вы можете убедиться, что МойНаследуемыйКласс
является тем, который вы хотите расширить, объявив его в пакете и затем расширив его
*/
Package('org.quickcorp.мойпакет1', [
	Class('МойНаследуемыйКласс', {
		источникПараметр: 1
	})
]);
```// Далее приведён пример определения MyExtendedClass в другом пакете
// org.quickcorp.package2
// расширяющий MyInheritedClass с использованием ClassFactory для получения класса из исходного пакета
// org.quickcorp.myPackage1
Package('org.quickcorp.мойпакет2',[
	Class('MyExtendedClass',ClassFactory('org.quickcorp.мойпакет1.MyInheritedClass'),{
		extendedParameter1: 'значение параметра',
		extendedParameter2: 2
	})
])

// Исправление имени пакета
Package('org.quickcorp.mypackage2',[
	Class('MyExtendedClass',ClassFactory('org.quickcorp.mypackage1.MyInheritedClass'),{
		extendedParameter1: 'значение параметра',
		extendedParameter2: 2
	})
])// это выведет число 1 (как наследованное значение параметра sourceProp)
console.log(New(МойРасширенныйКласс).источникПараметр)

_Crypt

С помощью _Crypt можно шифровать сериализуемые объекты с помощью пароля

Пример (1):

var _строка = New(_Crypt, {string: 'привет мир', key: 'некий ключ шифрования MD5'});
console.log(_строка._encrypt());
console.log(_строка._decrypt()); // расшифровывает зашифрованную строку до исходной

Пример (2):

_Crypt.encrypt('привет мир', '12345678866');
_Crypt.decrypt('nqCelFSiq6Wcpw==', '12345678866');

GLOBAL

GLOBAL — это специальный класс QCObjects для доступа к глобальному пространству имён. У него есть методы set и get для управления внутренними свойствами GLOBAL.

Пример:

GLOBAL.set('глобальноеСвойство1', 'некое значение в глобальном пространстве имён');
var глобальноеСвойство1 = GLOBAL.get('глобальноеСвойство1');

CONFIG

CONFIG — это умный класс для управления глобальными настройками вашего приложения. Вы можете получить значения свойств либо из файла config.json, либо из ранее сохранённых значений с помощью вызова set().

Использование из памяти:

  1. В вашем начальном коде установите начальные значения CONFIG:
CONFIG.set('некоеСвойствоНастроек', 'начальное значение');
  1. Затем вы можете получить эти значения из любого места вашего кода с помощью метода get:
var некоеСвойствоНастроек = CONFIG.get('некоеСвойствоНастроек');

Пример использования файла config.json:1.- Для начала следует указать, что вы используете файл config.json, установив значение "useConfigService" в true.

CONFIG.set('useConfigService', true); // использование файла config.json для настроек конфигурации

2.- После того как вы установили значение выше, QCObjects будет знать и искать следующие настройки CONFIG в файле config.json в папке basePath вашего приложения.

Пример использования зашифрованного файла config.json:

Существует возможность использовать зашифрованный файл config.json для защиты ваших настроек от роботов, которые могут украсть незащищенные данные с вашего веб-приложения (например, ключи API).

Чтобы зашифровать ваш JSON-файл, перейдите по адресу https://config.qcobjects.dev, введите домен и содержимое файла config.json. Инструмент зашифрует ваш JSON, и вы сможете скопировать зашифрованное содержимое для его вставки в файл config.json. QCObjects узнает, что данные зашифрованы, и процесс декодирования данных будет прозрачен для вас.

Динамические настройки CONFIG

Иногда вам потребуется установить значение из источника, который не является статическим, такого типа как переменные окружения или другой источник динамических данных. Чтобы получить значение с помощью CONFIG из динамического источника, вам нужно использовать процессор. Есть общие процессоры, заранее определённые, такие как $ENV (доступен только в CLI, Collab и Node) и $config (доступен во всех средах).Процессоры вызываются как мета-значение либо в файле config.json, либо в классе CONFIG.

// файл: config.json
{
	"domain": "localhost",
	"env1": "$ENV(ENV1)",
	"customSettings": {
		"value1": "$config(domain)"
	}
}
let value1 = CONFIG.get("customSettings").value1;
// value1 = "localhost";

let env1 = CONFIG.get("env1");
// env1 = (переменная окружения ENV1)
// устанавливает ключ "api_key" настроек CONFIG на динамический процессор $ENV, который получает значение API_KEY из переменных окружения
CONFIG.set("api_key", "$ENV(API_KEY)");

let api_key = CONFIG.get("api_key");
// api_key будет содержать значение переменной окружения API_KEY системы
// ($ENV процессор возвращает действительное значение только в Node.js, QCObjects CLI и QCObjects Collab движке)

Процессор

Статический класс, используемый для установки пользовательских процессоров для CONFIG.

Пример использования:

Processor.setProcessor(processor);

Где processor — это названная функция, которая принимает аргументы процессора.

Пример:

У вас есть переменная окружения с именем SERVICE_URL, которая хранит URL сервиса. Вам нужно использовать это значение в ваших конфигурационных настройках в поле serviceURL, но также вам нужно установить настройки host и port используя распарсенное значение этого URL. Чтобы распарсить значение переменной окружения SERVICE_URL по требованию и заполнить соответствующие настройки в вашем файле config.json, ваш файл config.json будет выглядеть следующим образом:```json // файл: config.json { "serviceURL": "$ENV(SERVICE_URL)", "host": "$SERVICE_HOST(SERVICE_URL)", "port": "$SERVICE_PORT(SERVICE_URL)" }


Обработчики **$SERVICE_HOST** и **$SERVICE_PORT** еще не существуют. Для их определения следует использовать:

```javascript
// выполните следующий код в вашем файле init.js или перед загрузкой конфигураций

let SERVICE_HOST = function (arg) {
	var processorHandler = this; // чтобы сделать этот код всегда рабочим, не используйте стрелочные функции при определении своих функций
	let serviceURL = new URL(processorHandler.processors.ENV(arg));
	return serviceURL.host;
};
let SERVICE_PORT = function (arg) {
	var processorHandler = this; // чтобы сделать этот код всегда рабочим, не используйте стрелочные функции при определении своих функций
	let serviceURL = new URL(processorHandler.processors.ENV(arg));
	return serviceURL.port;
};

Processor.setProcessor(SERVICE_HOST);
Processor.setProcessor(SERVICE_PORT);

Затем вам нужно установить переменную окружения SERVICE_URL в вашей оболочке

Это применимо только для систем Unix/Linux

export SERVICE_URL="https://example.com:443/path-to-a-resource/"

и ваши настройки будут динамически загружены следующим образом:

{
	"serviceURL": "https://example.com:443/path-to-a-resource/",
	"host": "example.com",
	"port": "443"
}

И вы получите соответствующие значения, используя CONFIG.get(value)

waitUntil

waitUntil — это вспомогательная функция, которую можно использовать в случае проблем с выполнением кода до тех пор, пока условие не станет истинным. Код внутри waitUntil будет выполнен один раз.ОБСЛУЖИВАНИЕ: Это полезно в некоторых случаях, но чрезмерное использование не рекомендуется.

Использование:

waitUntil(() => {
  // код, который будет выполнен после того, как условие станет истинным
}, () => { return condition; });
// где condition — то, что вы хотите ждать

Пример:

let someVar = 0;
waitUntil(() => {
  console.log('someVar есть');
}, () => { return typeof someVar !== 'undefined'; });
// где условие то, что вы хотите ждать

Пакет

Определяет пакет QCObjects и возвращает его.

Использование:

Package('packageName', [packageContent]);

Где packageContent это массив классов QCObjects. Если передается только параметр packageName, будет получен ранее объявленный контент пакета.

Пример (1):

'use strict';
Package('org.quickcorp.main', [
  Class('Main', InheritClass, {
    propertyName1: 'propertyValue1',
  }),
  Class('MyCustomClass', InheritClass, {
    propertyName2: 'propertyValue2',
  }),
]);

Пример (2):

let mainPackage = Package('org.quickcorp.main'); // это вернет ранее объявленный контент пакета 'org.quickcorp.main'
// mainPackage[0] будет определением класса Main.
// Это полезно для внутреннего анализа кода

Техника загрузки пакетов в QCObjects основана на промисах и ориентирована на области видимости. Вы можете проверить загружены ли пакеты, вызывая функцию Package() с аргументом имени пакета.

Импорт

Импортирует пакет из другого файла JavaScript#### Использование:

Import(packagename,[ready],[external]);

Где packagename — имя пакета, ready — функция, которая будет выполнена после загрузки пакета, а external — логическое значение, которое указывает, находится ли JS-файл в одной области или является внешним ресурсом.#### Пример (1):

Import('org.quickcorp.main');

Вышеуказанный код попытается импортировать файл JavaScript с названием 'org.quickcorp.main.js' из пути, указанного в значении настройки relativeImportPath вашего конфигурационного файла CONFIG. Внутри файла JavaScript вам следует объявить пакет, используя Package('org.quickcorp.main',[Class1, Class2...]).

Пример (2):

Import('org.quickcorp.main', function() {
  console.log('внешний импорт загружен');
}, true);

Вышеуказанный код теперь пытается загрузить тот же пакет, но использует внешний путь, определенный в настройках remoteImportsPath вашего конфигурационного файла CONFIG.

Замечание: В обоих вышеуказанных примерах расширение .js не используется или не специфицировано. Оно используется по умолчанию и не может быть изменено по причинам безопасности.

Экспорт

Установите символ (переменную или функцию) в глобальном пространстве имён.

Пример использования:

Export('имя_символа');

Пример:

(() => {
  // это локальное пространство имён
  let someFunction = (someLocalParam) => {
    console.log(someLocalParam);
  };
  Export(someFunction); // теперь someFunction находится в глобальном пространстве имён.
})();

// это глобальное пространство имён
someFunction('это работает');

Преобразование

Используйте метод Cast любого элемента DOM для получения свойств другого типа объекта. Это полезно для преобразования одного типа объекта в другой, что обеспечивает большую гибкость в вашем коде.#### Пример использования:

let resultObject = [элемент или тип QCObjects].cast(объектДляПреобразования);

Где объектДляПреобразования — это объект, из которого будут взяты свойства и помещены в возвращаемый объект resultObject методом cast.

Пример:

класс('МойСвойКласс', {
  prop1: '1',
  prop2: 2
});

let obj = document.createElement('div').cast(МойСвойКласс);

Вышеуказанный код создаёт объект DOM и преобразует его в МойСвойКласс. Поскольку МойСвойКласс является классом типа QCObjects, obj будет иметь свойства prop1 и prop2, а также станет экземпляром объекта QCObjects с телом, представляющим собой элемент div.

Тег

Функция тег полезна для выбора любых элементов DOM с помощью селекторов. тег всегда возвращает список элементов, который можно отображать, сортировать и фильтровать как любой другой список.

Пример использования:

var listOfElements = тег(селектор);

Где селектор — это селектор запроса DOM.

Пример:

<!DOCTYPE html>
<html>
    <head>
    	<title>Демо</title>
    	<script type="text/javascript" src="https://cdn.qcobjects.dev/QCObjects.js"></script>
    </head>
    <body>
    <div class="мойселектор">
    <p>Здравствуй мир</p>
    </div>
    <script>
    готово(()=>{
      тег('.мойселектор > p').map((element)=>{
        element.innerHTML = 'Здравствуй мир! Как дела?';
      });
    });
    </script>
    </body>
</html>
```В вышестоящем коде был создан параграф внутри div с CSS-классом "my-selector", затем он был динамически изменён с использованием функции Tag библиотеки QCObjects. Если вы знакомы с фреймворками для работы со селекторами, такими как jQuery, вам понравится эта функциональность.### Готово
Назначьте функцию выполнения после завершения всех действий QCObjects и события `window.onload`. Используйте её для предотвращения ошибок "неопределенного" объекта DOM.#### Пример использования:
```javascript
Ready(() => {
  // Ваш код инициализации здесь!
});

Обратите внимание, что если вы определяете динамические компоненты с помощью HTML-тега "component", загрузка динамического содержимого не будет триггерить события Ready. Чтобы поймать код каждый раз, когда загружается динамический компонент, используйте метод завершения контроллера вместо этого.

Вы будете использовать реализацию Ready в основном тогда, когда хотите внедрять объекты QCObjects вместе с другим фреймворком, который требует это.

Класс Компонента

Тип класса для компонентов в QCObjects.

Свойства

[Компонент].domain Возвращает строку с доменом вашего приложения. Это автоматически устанавливается QCObjects во время загрузки.

[Компонент].basePath Возвращает строку с базовым путём URL вашего приложения. Это автоматически устанавливается QCObjects во время загрузки.

ЗАМЕЧАНИЕ: Если вы хотите изменить базовый путь компонента, вам следует использовать _CONFIG.set('componentsBasePath', 'новый путь относительно домена') в вашем коде инициализации.[Компонент].templateURI Это строка, представляющая URI шаблона компонента относительно домена. Когда это свойство установлено, компонент будет загружать шаблон и добавлять внутренний контент как часть DOM. Для установки этого свойства рекомендуется использовать функцию помощника ComponentURI.[Компонент].tplsource Это строка, представляющая источник загрузки шаблона. Может быть "default" или "none". Значение "default" говорит QCObjects загружать шаблон из содержимого templateURI. Значение "none" говорит QCObjects не загружать шаблон откуда бы то ни было.

[Компонент].url Это строка, представляющая полный URL компонента. Это автоматически устанавливается QCObjects при создании компонента.

[Компонент].name Это строка, представляющая имя компонента. Имя компонента может быть любым алфавитно-цифровым значением, которое идентифицирует тип компонента. Оно используется внутри системы ComponentURI для создания нормализованного URI шаблона компонента.[Component].method Это строка, представляющая HTTP или HTTPS метод. По умолчанию, каждый компонент устанавливается для использования метода "GET". В большинстве случаев, вам не потребуется менять это свойство.[Component].data Это объект, представляющий данные компонента. При загрузке шаблона QCObjects получает каждое свойство объекта данных и связывает его с меткой шаблона, которая представляет то же свойство внутри содержимого шаблона между двойными фигурными скобками (например: {{prop1}} в содержимом шаблона будет представлять data.prop1 в экземпляре компонента). ЗАМЕЧАНИЕ: Для обновления привязок данных требуется перестроить компонент (см. использование метода [Component].rebuild() для получения более подробной информации).[Component].reload Это булево значение, которое указывает QCObjects, когда следует принудительно перезагружать содержимое компонента из шаблона или нет. Если его значение равно true, то содержимое шаблона заменит текущие дочерние элементы DOM тела компонента. Если значение равно false, то содержимое шаблона будет добавлено после последнего дочернего элемента тела компонента.[Component].caching This boolean value indicates to QCObjects whether caching of the given component is required or not. When a component is cached, the content loaded from the templateURI is loaded only once. You can set this property as a static class property for setting the default value for each subsequent instance of the component, or you can set an individual value for this property in each component definition. In a world where performance is paramount, the need to provide greater flexibility in caching behavior becomes more relevant than ever.

[Component].routing_mode Returns a string representation of the routing mode. Its value can be "hash", "pathname", or "search". NOTE: To change the routing mode for all components, it is recommended to use CONFIG.set('routingMode', 'valid routing mode value') in your initial code.

[Component].allowed_routing_modes Returns a list representing the valid routing modes. QCObjects uses this list internally for validating the correctness of the routing mode used when building component routes.[Component].routing_nodes Возвращает объект NodeList, представляющий список узлов, загруженных построителем маршрутизации компонента.[Component].routes Возвращает список маршрутов компонента, построенных при создании экземпляра компонента.

[Component].routePath Возвращает строковое представление текущего маршрута.

[Component].selectedRoute Возвращает объект, представляющий текущий маршрут компонента.

[Component].subcomponents Возвращает список компонентов, являющихся дочерними для данного экземпляра компонента.

[Component].body Это элемент DOM, представляющий тело компонента. ЗАМЕЧАНИЕ: Каждый раз, когда тело компонента устанавливается, это вызывает построитель маршрутизации для данного компонента.

Методы

[Component].set('property', value) Устанавливает значение для свойства компонента.

[Component].get('property') Возвращает значение свойства компонента.

[Component].rebuild() Перестраивает компонент. Это заставляет вызвать компонентLoader для данного компонента, если это необходимо.

[Component].cast(className or componentClassName) Возвращает преобразование определения компонента в другое. Это полезно для динамического объединения определений компонентов.

[Component].route() Принудительно заставляет конструктор маршрутов компонента перезагрузить маршруты компонента. Это приведёт к вызову перестроения при необходимости.[Компонент].fullscreen() Переводит компонент в полноэкранный режим.

[Компонент].closeFullscreen() Закрывает полноэкранный режим.

[Компонент].css(css объект) Устанавливает CSS свойства для компонента.

[Компонент].append(компонент или QCObjects объект) Добавляет компонент как потомка текущего компонента.

[Компонент].attachIn(селектор) Прикрепляет текущий компонент к любому элементу указанного селектора.

HTML-тег компонента

Это представление HTML-тега экземпляра компонента. Каждое объявление тега <component></component> создаёт связанный экземпляр компонента QCObjects. Хотя сам тег <component> не является экземпляром, вы можете даже определять некоторые свойства экземпляров, установив соответствующие атрибуты тега, когда они доступны.

Доступные атрибуты

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

Атрибут имени

<component name> Устанавливает имя связанного экземпляра компонента, созданного QCObjects.

Пример использования:
<component name="name_of_component"></component>
Пример:
<!-- index.html -->
<!DOCTYPE html>
<html>
    <head>
        <title>Демо</title>
        <script type="text/javascript" src="https://cdn.qcobjects.dev/QCObjects.js"></script>
    </head>
    <body>
      <!-- это загрузит содержимое файла ./templates/main[.tplextension] -->
      <component name="main"></component>
    </body>
</html>
Атрибут кеша

<component cached> Устанавливает свойство кеша для связанного экземпляра компонента.ЗАМЕЧАНИЕ: Только значение "true" может быть установлено, чтобы сообщить QCObjects, что содержимое шаблона компонента должно быть закешировано. Любое другое значение будет истолковано как "false".

Пример использования:
<component name="name_of_component" cached="true"></component>
Объявление тега свойства данных

<component data-property1 data-property2 ...> Устанавливает статическое значение свойства для объекта данных в экземпляре компонента. ЗАМЕЧАНИЕ: Объявление свойства данных было создано с целью предоставить простой способ имитации динамического компонента с привязками шаблона. Не используйте его, полагая, что это двустороннее связывание данных. Хотя вы можете получить поведение двустороннего связывания данных, обращаясь к объекту данных из экземпляра компонента, это не то же самое для тега компонента. Объявление свойства данных в тегах компонентов является односторонним связыванием данных из-за архитектуры дерева компонентов.

Атрибут controllerClass

<component controllerClass> Определяет пользовательский класс контроллера для экземпляра компонента

Пример использования:
<component name="name_of_component" controllerClass="ControllerClassName"></component>
Атрибут viewClass

<component viewClass> Определяет пользовательский класс представления для экземпляра компонента

Пример использования:
<component name="name_of_component" viewClass="ViewClassName"></component>
```##### Атрибут componentClass
**`<component componentClass>`**
Определяет пользовательский класс компонента для экземпляра компонента

###### Пример использования:
```html
<component name="name_of_component" componentClass="ComponentClassName"></component>
Атрибут effectClass

<component effectClass> Определяет пользовательский класс эффекта для экземпляра компонента

Пример использования:
<component name="name_of_component" effectClass="EffectClassName"></component>
Атрибут template-source

<component template-source> Устанавливает свойство tplsource связанного экземпляра компонента. Возможные значения — "none" или "default".

Пример использования:
<component name="name_of_component" template-source="none"></component>
Атрибут tplextension

<component tplextension> Устанавливает свойство tplextension связанного экземпляра компонента. Возможные значения — любое расширение файла. Значение по умолчанию — "html"

Пример использования:
<component name="name_of_component" tplextension="tpl.html"></component>

ComponentURI

Помощник для определения templateURI компонента в нормализованном виде.

Пример:
var templateURI = ComponentURI({
  'COMPONENTS_BASE_PATH': CONFIG.get('componentsBasePath'),
  'COMPONENT_NAME': 'main',
  'TPLEXTENSION': "tpl.html",
  'TPL_SOURCE': "default"
});
console.log(templateURI); // это будет показывать что-то вроде "templates/components/main.tpl.html", в зависимости от ваших CONFIG настроек
```#### componentLoader
Загружает экземпляр компонента на низком уровне и добавляет содержимое шаблона компонента в тело компонента. В большинстве случаев вам не потребуется вызывать `componentLoader`, чтобы загрузить компонент. Это автоматически вызывается QCObjects, когда это необходимо. `componentLoader` возвращает промис, который срабатывает при успешной загрузке компонента и отклоняется при неудачной загрузке.##### Пример использования:
```javascript
[Promise] componentLoader(componentInstance, load_async)

Где componentInstance — это экземпляр компонента, созданный методом _New(ComponentDefinitionClass)_.

Пример:
componentLoader(componentInstance, load_async).then(
  (successStandardResponse) => {
    // загрузка компонента выполнена успешно
    var request = successStandardResponse.request;
    var component = successStandardResponse.component;
  },
  (failStandardResponse) => {
    // загрузка компонента не удалась
    var component = failStandardResponse.component;
  }
);

buildComponents

Перестраивает каждый компонент, являющийся дочерним элементом элемента DOM, которому принадлежит данный метод. В большинстве случаев вам не потребуется вызывать buildComponents, чтобы построить или перестроить все компоненты в DOM. Это автоматически вызывается QCObjects, когда это необходимо.

Пример использования:
[element].buildComponents()
Пример:
document.buildComponents()

Контроллер

Встроенный тип класса QCObjects для определения контроллера

Представление

Встроенный тип представления QCObjects для определения представления

Объект значения

Встроенный тип класса QCObjects для определения объекта значения

Сервис

Тип класса QCObjects для сервисов.

Свойства

[Сервис].домен Возвращает строку с доменом вашего приложения. Устанавливается автоматически QCObjects при запуске.

[Сервис].базовыйПуть Возвращает строку с базовым путём URL вашего приложения. Устанавливается автоматически QCObjects при запуске.[Сервис].url Это строка, представляющая полный URL сервиса. Она может быть абсолютной или относительной к базовому пути, если применимо. Также она может быть внешним URL.

ЗАМЕЧАНИЕ: Для загрузки сервиса внешнего ресурса вам необходимо указать параметр внешний как true при использовании serviceLoader.

Строка, представляющая имя компонента. Имя сервиса может быть любой алфавитно-цифровой последовательностью, которая идентифицирует экземпляр сервиса. Это не уникальный идентификатор, а просто описательное имя.

**[Сервис].метод**
Строка, представляющая HTTP или HTTPS метод. Возможные значения включают: "GET", "POST", "PUT" и так далее — любое другое значение, которое принимается вызовами REST сервисов.

**[Сервис].data**
Объект, представляющий данные сервиса. Когда QCObjects загружает сервис, он получает ответ и интерпретирует его как шаблон. Поэтому после получения ответа от сервиса каждое свойство объекта данных будет связано с меткой шаблона, представляющей то же свойство внутри содержимого шаблона между двойными фигурными скобками (например, {{prop1}} в контенте шаблона будет представлять собой data.prop1 в экземпляре сервиса).
```**[Service].cached**
Логическое значение, указывающее, требуется ли кэширование ответа сервиса или нет. Когда сервис кэшируется, содержимое шаблона, загруженное с помощью URL сервиса, загружается только один раз. Вам следует установить это значение как false для каждого экземпляра сервиса, чтобы гарантировать, что сервис загружается из ресурса, а не из кэша.#### Методы
**[Service].set('prop', value)**
Устанавливает значение для свойства сервиса.

**[Service].get('prop')**
Возвращает значение свойства сервиса.


### serviceLoader
Загружает экземпляр сервиса и возвращает промис, который выполняется при успешной загрузке ответа сервиса и отклоняется при неудачной загрузке ответа.

#### Пример использования:
```javascript
[Promise] serviceLoader(serviceInstance)

Пример:

Class('MyTestService', Service, {
    name: 'myservice',
    external: true,
    cached: false,
    method: 'GET',
    headers: {'Content-Type': 'application/json'},
    url: 'https://api.github.com/orgs/QuickCorp/repos',
    withCredentials: false,
    _new_: () => {
        // сервис создан
    },
    done: () => {
        // сервис загружен
    }
});
var service = serviceLoader(New(MyTestService, {
    data: {param1: 1}
})).then(
    (successfulResponse) => {
        // Это выведет ответ сервиса как обычный текст
        console.log(successfulResponse.service.template);
    },
    (failedResponse) => {

    }
);

JSONService

Предопределенное определение класса для JSON сервиса

Свойства

[JSONService].domain Возвращает строку с доменом вашего приложения. Устанавливается автоматически при загрузке QCObjects.

[JSONService].basePath Возвращает строку с базовым путем URL вашего приложения. Устанавливается автоматически при загрузке QCObjects.

[JSONService].url Строковое представление полного URL сервиса. Может быть абсолютным или относительным к basePath, если применимо. Также может быть внешним URL.

ЗАМЕЧАНИЕ: Для загрузки сервиса внешнего ресурса вам нужно указать параметр external в значение true при использовании serviceLoader.[JSONService].name Строковое представление имени компонента. Имя сервиса может быть любым алфавитно-цифровым значением, которое идентифицирует экземпляр сервиса. Это не уникальный идентификатор, а просто описательное имя.

[JSONService].method Строковое представление метода HTTP или HTTPS. Возможные значения: "GET", "POST", "PUT", ... любой другой, который принимает вызовы REST сервисов.

[JSONService].data Объект, представляющий данные сервиса. Когда QCObjects загружает сервис, он получает ответ и интерпретирует его как шаблон. Поэтому после получения ответа от сервиса каждое свойство объекта данных будет связано с меткой шаблона, представляющей то же свойство внутри содержимого шаблона между двойными фигурными скобками (например: {{prop1}} в содержимом шаблона будет представлять data.prop1 в экземпляре сервиса).

[JSONService].cached Логическое значение, которое сообщает QCObjects, требуется ли кэширование ответа сервиса или нет. При кэшировании контента шаблона, загруженного с URL сервиса, он загружается только один раз. Вам следует установить это значение в false для каждого экземпляра сервиса, чтобы гарантировать, что сервис загружается из ресурса, а не из кэша хранения.

Методы

[JSONService].set('prop', value) Устанавливает значение для свойства сервиса.[JSONService].get('prop') Возвращает значение свойства сервиса.#### Пример:

Class('MyTestJSONService', JSONService, {
    name: 'myJSONservice',
    external: true,
    cached: false,
    method: 'GET',
    withCredentials: false,
    url: 'https://api.github.com/orgs/QuickCorp/repos',
    _new_: function () {
        // сервис создан
        delete this.headers.charset; // не отправлять заголовок charset
    },
    done: function (result) {
        _super_('JSONService', 'done').call(this, result);
    }
});
var service = serviceLoader(New(MyTestJSONService, {
    data: { param1: 1 }
})).then(
    (successfulResponse) => {
        // Это покажет ответ сервиса в виде объекта JSON
        console.log(successfulResponse.service.JSONresponse);
    },
    (failedResponse) => {}
);
```### Класс ConfigService
Загружает конфигурационные настройки из файла `config.json`.

#### Пример:
```javascript
// Устанавливаем относительный путь до файла config.json
ConfigService.configFileName = 'config.json'; // это делается по умолчанию
CONFIG.set('useConfigService', true); // использование config.json для настроек

Класс SourceJS

Статический класс для загрузки внешних зависимостей JavaScript. Часто используется для загрузки библиотек, которые находятся вне пакетной системы QCObjects.

Пример:

Class("MyNewController", Controller, {
    _new_: function () {
        var controller = this;
        controller.dependencies.push(
            New(SourceJS, {
                external: false,
                url: 'doc/js/my-js-resource.js',
                done: function () {
                    logger.debug("Зависимость загружена");
                }
            })
        );
    }
});

Класс SourceCSS

Статический класс для загрузки внешнего ресурса CSS.

Class("MyNewController", Controller, {
    dependencies: [],
    done: function () {
        this.dependencies.push(New(SourceCSS, {
            external: false,
            url: CONFIG.get('basePath') + 'css/my-css-resource.css'
        }));
    }
});

Класс Effect

Суперкласс для определения пользовательских эффектов.

Пример:

Class('CustomFade', Effect, {
    duration: 500, // миллисекунды длительности
    apply: function () {
        // Вы должны использовать следующую строку для применения эффекта затухания в реальном времени
        _super_('Fade', 'apply').apply(this, arguments);
    }
});

Класс Timer

Особая реализация метода requestAnimationFrame для эмуляции создания экземпляров потока, что позволяет эффективнее управлять параллельным выполнением задач в реальном времени.ПРИМЕЧАНИЕ: Поскольку этот метод зависит от наличия requestAnimationFrame, он работает только в современных браузерах.

Пример:

Timer.thread({
        duration:300, // длительность в миллисекундах
        timing(timeFraction, elapsed){
            return timeFraction; // вы можете изменить эту строку, чтобы вернуть пользовательскую математическую функцию для временной шкалы
        },
        intervalInterceptor(progress){
            if (progress >= 100){
                // делайте то, что вам нужно здесь
            }
        }
});

Списковые и Математические Функции

Класс ArrayList

Класс для управления списками

let myVar = New(ArrayList, [1, 2, 3]);

Класс ArrayCollection

Расширенное определение для продвинутого управления коллекциями

let collection = New(ArrayCollection, { source: [0, 1, 2] });

[ArrayList или Array].unique

Фильтрует массив или объект типа ArrayList, чтобы получить только уникальные элементы. ЗАМЕЧАНИЕ: Он фильтрует только последовательность одного значения.

let myUniqueList = [0, 1, 2, 1, 2].unique();
// будет иметь вид: myUniqueList = [0, 1, 2]

[ArrayList или Array].table

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

['a', 'b', 'c', 'd'].table();
// это покажет
┌─────────┬───────┐
 (index)  Value 
├─────────┼───────┤
    0      'a'  
    1      'b'  
    2      'c'  
    3      'd'  
└─────────┴───────┘

[ArrayList или Array].sortСортирует элементы массива или списка.

let my_sorted_array = [3,3,4,0,2,1].sort();
// my_sorted_array = [ 0, 1, 2, 3, 3, 4 ];
let my_sorted_list = New(ArrayList, { source: [3,3,4,0,2,1] }).source.sort();
// my_sorted_list = [ 0, 1, 2, 3, 3, 4 ];

[ArrayList или Array].sortBy

Сортирует список объектов по значению свойства.

let my_ordered_list = [
    {"b":1,"a":2},
    {"b":2,"a":1},
    {"b":3,"a":3}
].sortBy("a");
// это приведёт к следующему результату
[
    { b: 2, a: 1 },
    { b: 1, a: 2 },
    { b: 3, a: 3 }
];

[ArrayList или Array].matrix

Генерирует матрицу в одном измерения.

Использование

[].matrix (длина, [значение]) Где длина — количество элементов, а необязательный значение — значение каждого элемента, может быть любым типом данных.

let matrix = Array.matrix(10);
// matrix = [
    0, 0, 0, 0, 0,
    0, 0, 0, 0, 0
];
let matrix = ArrayList.matrix(10, 1);
// matrix = [
    1, 1, 1, 1, 1,
    1, 1, 1, 1, 1
];
let a = 1, b = 2;
let c = ArrayList.matrix(10, { a, b });
// c = [
    { a: 1, b: 2 },
    { a: 1, b: 2 },
    { a: 1, b: 2 },
    { a: 1, b: 2 },
    { a: 1, b: 2 },
    { a: 1, b: 2 },
    { a: 1, b: 2 },
    { a: 1, b: 2 },
    { a: 1, b: 2 },
    { a: 1, b: 2 }
];

[ArrayList или Array].matrix2d

Создает двумерную матрицу.

let matrix2d = ArrayList.matrix2d(2, 1);
// [ [ 1, 1 ], [ 1, 1 ] ]

[ArrayList или Array].matrix3d

Создает трехмерную матрицу.

let matrix3d = ArrayList.matrix3d(3, "a");
// это приведет к созданию 3x3 матрицы со значением "a" в каждом элементе
[
    [ [ 'a', 'a', 'a' ], [ 'a', 'a', 'a' ], [ 'a', 'a', 'a' ] ],
    [ [ 'a', 'a', 'a' ], [ 'a', 'a', 'a' ], [ 'a', 'a', 'a' ] ],
    [ [ 'a', 'a', 'a' ], [ 'a', 'a', 'a' ], [ 'a', 'a', 'a' ] ]
];

ДиапазонФункция, аналогичная Python range, для создания списка диапазона. Вы можете использовать её вместе с ArrayList.matrix, ArrayList.matrix2d и ArrayList.matrix3d для генерации сложных диапазонов матриц.

Использование

range(длина) или range(начальный_индекс, конечный_индекс) range() без параметров вернёт пустой список range(0) вернёт список с одним элементом со значением 0

logger.debugEnabled=true;

for (var i in range(10)){
	(!isNaN(i) && logger.debug(i))
}

// вышеуказанный код покажет
[DEBUG] 0
[DEBUG] 1
[DEBUG] 2
[DEBUG] 3
[DEBUG] 4
[DEBUG] 5
[DEBUG] 6
[DEBUG] 7
[DEBUG] 8
[DEBUG] 9
logger.debugEnabled=true;

// тот же результат будет получен при итерации через диапазон первым
for (var i in {...range(10)}){
	logger.debug(i)
}

// вышеуказанный код покажет
[DEBUG] 0
[DEBUG] 1
[DEBUG] 2
[DEBUG] 3
[DEBUG] 4
[DEBUG] 5
[DEBUG] 6
[DEBUG] 7
[DEBUG] 8
[DEBUG] 9
// немного короче синтаксис для того же результата
range(10).map(n => logger.debug(n))
let normalizedMatrix = ArrayList.matrix(3, range(2));
// normalizedMatrix = [ [ 0, 1, 2 ], [ 0, 1, 2 ], [ 0, 1, 2 ] ]
let my3dmatrix = ArrayList.matrix3d(3, range(0, 1));
// my3dmatrix будет
[
  [
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ]
  ],
  [
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ]
  ],
  [
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
    [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ]
  ]
]

Array.sum

Вычисляет сумму элементов массива.

let s = [1, 2, 3].sum();
// s = 6

Array.avg

Вычисляет среднее значение элементов массива.

let average = [10, 5].avg();
// average = 7.5
```### Array.min

Возвращает минимальное значение из элементов массива.

```javascript
let minValue = [1,2,3].min();
// minValue = 1

Array.max

Возвращает максимальное значение из элементов массива.

let maxValue = [1,2,3].max();
// maxValue = 3

SDK

Компоненты SDK

org.quickcorp.components.ShadowedComponent

Класс ShadowedComponent предназначен для создания компонента с использованием Shadow DOM браузера. Узнайте больше о Shadowed Components в этой статье на Hackernoon.

Пример использования:
<component componentClass="ShadowedComponent"></component>

org.quickcorp.components.FormField

Класс FormField предназначен для внедрения поведения формы в ваши компоненты QCObjects. Он имеет обратную связь данных для обнаружения значений полей формы внутри вашего компонента и привязки этих значений к данным вашего компонента. Таким образом, вы не теряете производительность, используя старый метод двухсторонней привязки данных на основе наблюдаемых значений. Для реализации этого продвинутого поведения вам следует выполнить следующие шаги:

  1. Назначьте атрибут data-field к тегу DOM внутри тела компонента, указав соответствующее имя поля в объекте данных.

  2. Назначьте FormField в атрибуте componentClass вашего компонента.3. Чтобы получить данные формы внутри вашего компонента, просто используйте объект componentInstance.data. Каждое свойство объекта componentInstance.data будет связано событиями привязки данных со значениями каждого поля формы, имеющего назначенное значение data-field.##### Пример использования:

<!-- Где вы размещаете компонент -->
<component name="myform" componentClass="FormField"></component>
<!-- шаблон: myform.tpl.html -->
<label for="email"><b>Email</b></label>
<input data-field="email" type="email" placeholder="Введите Email" name="email" required>

<label for="psw"><b>Пароль</b></label>
<input data-field="name" type="text" placeholder="Введите Ваше Имя" name="name" required>

Атрибут data-field="name" будет связан с this.data.name внутри класса компонента и будет обновлен каждый раз, когда происходит событие привязки данных. То же самое относится к data-field="email" и так далее.

FormField.executeBindings():

Метод executeBindings компонента FormField найдет значения атрибута data-field и сопоставит их с соответствующими полями data в экземпляре компонента.

Событие привязки данных Change:

Внутри тела вашего компонента, когда это компонент FormField, каждый раз, когда DOM отправляет событие "change", вызывается метод executeBindings вашего компонента.

Событие привязки данных Blur:

Внутри тела вашего компонента, когда это компонент FormField, каждый раз, когда DOM отправляет событие "blur", вызывается метод executeBindings вашего компонента.

Событие привязки данных Focus:

Внутри тела вашего компонента, когда это компонент FormField, каждый раз, когда DOM отправляет событие "focus", вызывается метод executeBindings вашего компонента.

Событие привязки данных Keydown:Внутри тела вашего компонента, когда это компонент FormField, каждый раз, когда DOM отправляет событие "keydown", вызывается метод executeBindings вашего компонента.#### org.quickcorp.components.ButtonField

ButtonField является подклассом FormField, который обычно используется для выполнения аналогичных задач, как и FormField. Основное различие между ButtonField и FormField заключается в том, что ButtonField имеет элемент DOM <button> в качестве тела компонента по умолчанию. В то время как FormField не имеет заранее определенного тела.

Пример использования:
<component name="name_of_component" componentClass="ButtonField"></component>

org.quickcorp.components.InputField

InputField является подклассом FormField, который обычно используется для выполнения аналогичных задач, как и FormField. Основное различие между InputField и FormField заключается в том, что InputField имеет элемент DOM в качестве тела компонента по умолчанию. В то время как FormField не имеет заранее определенного тела.

Пример использования:
<component name="name_of_component" componentClass="InputField"></component>

org.quickcorp.components.TextField

TextField является подклассом FormField, который обычно используется для выполнения аналогичных задач, как и FormField. Основное различие между TextField и FormField заключается в том, что TextField имеет элемент DOM <textarea> в качестве тела компонента по умолчанию. В то время как FormField не имеет заранее определенного тела.

Пример использования:
<component name="name_of_component" componentClass="TextField"></component>

org.quickcorp.components.EmailFieldEmailField — это подкласс компонента FormField, который обычно используется для аналогичной цели, как и сам FormField. Основное различие между ButtonField и FormField заключается в том, что ButtonField имеет элемент DOM <input> в качестве своего содержимого по умолчанию. В то время как FormField не имеет заранее определённого содержимого.##### Пример использования:

<component name="name_of_component" componentClass="EmailField"></component>

org.quickcorp.components.GridComponent

GridComponent имеет заранее назначенное имя со значением "grid". Поэтому будьте внимательны при использовании этого типа компонентов. Также GridComponent предназначен для использования вместе с GridController для расширения его поведения до CSS Grid.

Пример использования:
<component componentClass="GridComponent" ...></component>
Пример:
<component rows="2" cols="2" componentClass="GridComponent" controllerClass="GridController">
  <!-- рекомендуется использовать подкомпоненты в качестве элементов сетки -->
	<component name="name_of_subcomponent1"></component>
	<component name="name_of_subcomponent2"></component>
	<component name="name_of_subcomponent3"></component>
	<component name="name_of_subcomponent4"></component>
</controller>

Приведённый выше пример создаёт CSS-сетку с двумя столбцами и двумя строками и помещает подкомпоненты внутрь неё.

Не забудьте этот файл:

<!-- файл: grid.tpl.html, вы можете использовать шаблон сетки либо для отображения самой сетки, либо для отображения информации о загрузке -->
<p>Загрузка сетки...</p>

org.quickcorp.components.ModalEnclosureComponent

org.quickcorp.components.ModalComponent

org.quickcorp.components.SwaggerUIComponent

Этот компонент используется для внедрения необходимых DOM-элементов Swagger UI для работы с API Swagger UI. Подробнее читайте в статье блога разработчиков QCObjects под названием Работа с Swagger UI как с компонентом QCObjects.##### Пример использования:

<component componentClass="SwaggerUIComponent" controllerClass="SwaggerUIController"></component>

org.quickcorp.components.splashscreen.VideoSplashScreenComponent

Сильное определение компонента для возможности создания впечатляющего видео-экрана запуска для вашего прогрессивного веб-приложения.

Пример:
<!-- Добавьте тег компонента экрана запуска как первый компонент в вашем HTML документе -->
<component componentClass="VideoSplashScreenComponent"
	data-background="./img/splash/splashscreen-aqua.png"
	data-video_mp4="./img/splash/splashscreen-aqua.mp4"
	data-video_webm="./img/splash/splashscreen-aqua.webm"
	data-video_ogg="./img/splash/splashscreen-aqua.ogv" duration="5000">
	<img slot="logo" alt="Логотип" src="./img/logo-qcobjects-white.svg"/>
</component>
<!-- Затем вы можете поместить основной компонент так же, как обычно -->
<component name="main" cached=true controllerClass="MainController">
</component>

Контроллеры SDK

org.quickcorp.controllers.GridController

Класс GridController предназначен для использования вместе с компонентом GridComponent, чтобы позволить вам создать сетку CSS для размещения подкомпонентов. Подробнее в org.quickcorp.components.GridComponent.

org.quickcorp.controllers.DataGridControllerКласс DataGridController будет использовать данные вашего компонента для отображения множества подкомпонентов. Это часто используется для отображения динамического списка компонентов. Он использует значение атрибута subcomponentClass в теге компонента для определения того, какой шаблон компонента использовать для построения каждого подкомпонента. Данные каждого подкомпонента будут заполнены значением элемента, связанного с этим подкомпонентом.##### Использование:

<component name="name_of_component" controllerClass="DataGridController" subcomponentClass="SubComponentClass">
</component>
Пример:

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

Поэтому вы определяете компонент CardComponent для отображения фотографии, имени и электронной почты элемента в списке.

Class("CardComponent", Component, {
	name: "card", // это будет указывать на templates/components/card.tpl.html
	data: { // значение этого объекта будет перезаписываться контроллером DataGridController
		name: "<имя контакта>",
		email: "email@example.com",
		profilePicture: "img/photo.png"
	}
})
<!-- шаблон: card.tpl.html -->
<img src="{{profilePicture}}" />
<h3>{{name}}</h3>
<p>{{email}}</p>

Затем вам нужно поместить компонент для генерации списка карточек.

<component name="loading_list" componentClass="MyListComponent" controllerClass="DataGridController"
	subcomponentClass="CardComponent">
</component>
<!-- шаблон: loading_list.tpl.html -->
<p>Загрузка списка...</p>

Последним шагом является определение MyListComponent для присвоения динамических данных списка.```javascript Class("MyListComponent", Component, { data:[ { // значение этого объекта будет отображено в подкомпоненте с помощью DataGridController name:"<имя контакта>", email:"email@example.com", profile_picture:"img/photo.png" }, { // значение этого объекта будет отображено в подкомпоненте с помощью DataGridController name:"<имя контакта>", email:"email@example.com", profile_picture:"img/photo.png" }, { // значение этого объекта будет отображено в подкомпоненте с помощью DataGridController name:"<имя контакта>", email:"email@example.com", profile_picture:"img/photo.png" } ] })


#### org.quickcorp.controllers.ModalController

#### org.quickcorp.controllers.FormValidations

Класс **FormValidations** используется для управления базовыми проверками формы для контроллера **FormController**.

#### Пример использования:

```html
FormValidations.getDefault(validationName)

Где validationName — это имя проверки, которое должно быть указано в свойстве validations контроллера FormController.

org.quickcorp.controllers.FormController

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

  • Укажите сервисный класс
  • Определите параметры формы
  • Укажите или запрограммируйте проверки полей
[FormController].serviceClass

Это строковое имя определения класса. Контроллер формы использует функцию помощника ClassFactory для загрузки этого класса, поэтому имя может содержать полное имя пакета и определения.

[FormController].formSettings

Это объект с особыми свойствами формы. По умолчанию настройки следующие: backRouting:'#', loadingRouting:'#loading', nextRouting:'#signupsuccessful'. Эти настройки предназначены для управления поведением потока формы.loadingRouting — это имя маршрута, которое будет запущено во время вызова serviceClass до получения ответа от сервисного загрузчика.

backRouting — это имя маршрута, которое будет запущено, если вызов serviceClass завершится ошибкой.

nextRouting — это имя маршрута, которое будет запущено при успешном завершении вызова serviceClass.

[FormController].validations

Это объект с вспомогательными функциями проверки каждого поля формы. Когда вы определяете функцию проверки для поля, FormController будет запрашивать выполнение этой функции перед отправкой формы, если она вернёт true.

Чтобы определить проверки для полей формы, вам просто нужно добавить их как часть свойства validations.

Пример использования:
    // Допустим, что у вас есть поле формы с названием "name"
    validations: {
        name () {
            return (fieldName, dataValue, element) => {
                return [true ... или условие false];
            };
        },
    }, //... добавьте проверку для каждого поля формы, которое требуется проверять

Вы также можете использовать FormValidations.getDefault для простоты.

    // Допустим, что у вас есть поле формы с названием "name"
    validations: {
        name () {
            return FormValidations.getDefault('name');
        },
    }, //... добавьте проверку для каждого поля формы, которое требуется проверять
[FormController].formSaveTouchHandler

Этот метод внутренне используется FormController для вызова serviceClass как действия отправки формы. Он привязывается к любому событию клика или прикосновения любого элемента внутри формы, имеющего CSS-класс ".submit".Пример:

<button class="submit"><p>Отправить</p></button>

Когда происходит событие клика или прикосновения вышеупомянутой кнопки, FormController вызывает сервис, определённый в serviceClass. Это действие выполняется методом formSaveTouchHandler. Если вы хотите изменить это поведение, просто переопределите этот метод в вашем пользовательском контроллере.

Полный пример FormController

Ниже представлен полный пример определения формы регистрации с использованием FormController.

// Сначала определим сервисный класс, который будет вызван при отправке.
Class('SignupClientService', JSONService, {
    name: 'signup',
    external: true,
    cached: false,
    method: 'POST',
    url: Service.basePath + 'createaccount',
    withCredentials: false,
    _new_: () => {
        // сервис был создан
    },
    done: (successfulResponse) => {
        // сервис загружен
        _super_('JSONService', 'done').call(successfulResponse.service, successfulResponse);
        console.log(successfulResponse.service.JSONresponse);
    }
});
``````javascript
// Чтобы безопасно расширить FormController, мы сначала расширяем от Controller, затем используем defaultController для создания нового объекта FormController
Class('SignupFormController', Controller, {
    serviceClass: 'SignupClientService',
    formSettings: { /* маршруты, которые будут запущены после вызова serviceClass */
        backRouting: '#',
        loadingRouting: '#loading',
        nextRouting: '#signupsuccessful'
    },
    validations: { /* определение валидации для каждого поля формы перед отправкой */
        name() {
            return FormValidations.getDefault('name')
        },
        email() {
            return FormValidations.getDefault('email')
        },
        comment(fieldName, dataValue, element) {
            return (dataValue !== '') ? true : false;
        }
    },
    defaulController: null,
    _new_: function(o) {
        o.serviceClass = this.serviceClass;
        o.formSettings = this.formSettings;
        o.validations = this.validations;
        // здесь мы создаем новый объект defaultController с использованием New FormController
        // передаем объект o, который получен из процесса сборки компонентов.
        this.defaulController = New(FormController, o);
    },
    done: function() {
        // определяем пользовательскую функцию обратного вызова done для внедрения пользовательского поведения, а также вызываем поведение defaultController
        logger.debugEnabled = true;
        var controller = this.defaulController;
        try {
            controller.done.call(controller);
        } catch (e) {
            logger.debug('Не удалось выполнить стандартное поведение');
        }
    }
})
``````html
<!-- Тень компонента для отображения формы регистрации -->
<!-- шаблон: signup-form.tpl.html -->
```<form action="#" style="border: 1px solid #ccc; border-radius: 20px;">
     <div class="container">
         <slot name="title">
             <h1>Форма регистрации</h1>
         </slot>
         <slot name="subtitle">
             <p>Пожалуйста, заполните эту форму для запроса предложения.</p>
         </slot>
         <hr/>
         <slot id="field_control" name="field-control">
         </slot>
         <hr/>
         <slot name="submit_button"></slot>
     </div>
 </form>

```html
<!-- Форма регистрации с использованием затенённого компонента signup-form -->
<!-- Шаблон: signup.tpl.html -->
<component name="signup-form" shadowed="true" controller-class="SignupFormController">
    <h1 slot="title">Форма регистрации</h1>
    <p slot="subtitle">Пожалуйста, заполните эту форму для запроса предложения.</p>
    <label slot="field-control" id="name_label" for="name"><b>👤 Полное имя</b></label>
    <input slot="field-control" type="text" pattern="^[a-zA-Z]+(([',.  -][a-zA-Z ])?[a-zA-Z]*)*$" title="Введите ваше полное имя" placeholder="Полное имя" name="name" data-field="name" aria-labelledby="name_label" required>
    <label slot="field-control" id="email_label" for="email"><b>📧 Электронная почта</b></label>
    <input slot="field-control" type="email" pattern="^[\\w-\\. ]+@([\\w-]+\\. )+[\\w-]{2,4}$" title="Введите правильный адрес электронной почты" placeholder="Введите адрес электронной почты" name="email" data-field="email" aria-labelledby="email_label" required>
    <label slot="field-control" for="comment" id="comment_label"><b>💬 Комментарий</b></label>
    <textarea slot="field-control" name="comment" title="Введите комментарий" rows="10" cols="100" data-field="comment" aria-labelledby="comment_label"></textarea>
    <p slot="field-control">Отправляя эту форму вы соглашаетесь с нашими <a href="#" style="color:dodgerblue">Условиями использования и политикой конфиденциальности</a>.</p>
    <div class="clearfix">
        <button aria-label="Отмена" onclick="location.href='javascript:void(0);'">
            Отмена
        </button>
        <button aria-label="Отправить" onclick="location.href='javascript:void(0);'">
            Отправить
        </button>
    </div>
</component>
``````html
<div>
    <button href='/#'" role="button" tabindex="-1" type="button" class="cancelbtn">
        <p>Отмена</p>
    </button>
    <button aria-label="Submit" role="button" tabindex="-1" type="button" class="signupbtn submit">
        <p>Submit</p>
    </button>
</div>
<component>
<div>
    <button href='/#' role="button" tabindex="-1" type="button" class="cancelbtn">
        <p>Отмена</p>
    </button>
    <button aria-label="Submit" role="button" tabindex="-1" type="button" class="signupbtn submit">
        <p>Submit</p>
    </button>
</div>
<component>
```#### org.quickcorp.controllers.SwaggerUIController

Используется для внедрения необходимого DOM для Swagger UI API. Узнайте больше в этой статье блога QCObjects Developers под названием [Работа с Swagger UI как с компонентом QCObjects](https://devblog.qcobjects.org/working-with-swagger-ui-as-a-qcobjects-component-ck6xzoqkg05indfs1i4rxq72e).

##### Пример использования:
```html
<component componentClass="SwaggerUIComponent" controllerClass="SwaggerUIController"></component>

SDK EffectsQCObjects имеет определение эффекта, которое используется для управления и создания новых эффектов и переходов для компонентов.

Ниже приведены некоторые пользовательские определения эффектов, которые помогут вам создать впечатляющие визуальные возможности для ваших компонентов. Для повышения производительности эффекты изменяют CSS внутренне, чтобы применять эффект наиболее эффективным образом. А вся система эффектов основана на определении requestAnimationFrame, подробнее здесь

org.quickcorp.tools.effects.Move

Перемещает объект DOM с одной позиции на другую.

Пример использования:
Move.apply(element, xfrom, yfrom, xto, yto);
Пример:
// следующая строка переместит все изображения с (0,0) на (10,10)
Tag("img").map(img => Move.apply(img, 0, 0, 10, 10));

org.quickcorp.tools.effects.MoveXInFromRight

Перемещает элемент с правой стороны по оси X в исходное положение объекта.

Пример использования:```javascript

MoveXInFromRight.apply(element)


##### Пример:

```javascript
// следующая строка переместит каждый canvas на странице с правой стороны в исходное положение
Tag('canvas').map(canvas => MoveXInFromRight.apply(canvas));

org.quickcorp.tools.effects.MoveXInFromLeft

Перемещает элемент с левой стороны по оси X в исходное положение объекта.

Пример использования:
MoveXInFromLeft.apply(element)
Пример:
// следующая строка переместит каждый canvas на странице с левой стороны в исходное положение
Tag('canvas').map(canvas => MoveXInFromLeft.apply(canvas));

org.quickcorp.tools.effects.MoveYInFromBottom

Перемещает объект DOM с нижней части по оси Y в исходное положение.

Пример использования:
MoveYInFromBottom.apply(element)
Пример:
// следующая строка переместит тело каждого компонента с названием "comp1" снизу в его исходное положение
Tag('component[name=comp1]').map(componentBody => MoveYInFromBottom.apply(componentBody));

org.quickcorp.tools.effects.MoveYInFromTop

Перемещает объект DOM с верхней части по оси Y в исходное положение.

Пример использования:
MoveYInFromTop.apply(element)
Пример:
// следующая строка переместит тело каждого компонента с названием "comp1" сверху в его исходное положение
Tag('component[name=comp1]').map(componentBody => MoveYInFromTop.apply(componentBody));

org.quickcorp.tools.effects.RotateX

Поворачивает объект по оси X.

Пример использования:
RotateX.apply(element, angleFrom, angleTo)
```**angleFrom** и **angleTo** представляют значения угла, выраженные в градусах, от 0 до 360.

##### Пример:
```javascript
// следующая строка повернет div с id #id по оси X с 180 градусов до 240 градусов
Tag('div#id').map(div => RotateX.apply(div, 180, 240));

org.quickcorp.tools.effects.RotateY

Поворачивает объект вокруг оси Y.

Пример использования:
RotateY.apply(element, angleFrom, angleTo)

angleFrom и angleTo представляют значения угла в градусах, от 0 до 360.

Пример:
// следующая строка повернет объект с id `#id` вокруг оси Y от 0 до 270 градусов
Tag('div#id').map(div => RotateY.apply(div, 0, 270));

org.quickcorp.tools.effects.RotateZ

Поворачивает объект вокруг оси Z.

Пример использования:
RotateZ.apply(element, angleFrom, angleTo)

angleFrom и angleTo представляют значения угла в градусах, от 0 до 360.

Пример:
// следующая строка повернет объект с id `#id` вокруг оси Z от 0 до 60 градусов
Tag('div#id').map(div => RotateZ.apply(div, 0, 60));

org.quickcorp.tools.effects.Rotate

Поворачивает объект вокруг осей X, Y и Z одновременно, создавая эффект трехмерного поворота.

Пример использования:
Rotate.apply(element, angleFrom, angleTo)

angleFrom и angleTo представляют значения угла в градусах, от 0 до 360.

Пример:
// следующая строка повернет объект с id `#id` вокруг осей X, Y и Z от 0 до 270 градусов
Tag('div#id').map(div => Rotate.apply(div, 0, 270));

org.quickcorp.tools.effects.FadeСоздает эффект плавного затухания путем изменения прозрачности элемента.

Пример использования:
Fade.apply(element, прозрачностьОт, прозрачностьДо)

прозрачностьОт и прозрачностьДо — это числа от 0 до 1.

// следующая строка будет плавно увеличивать видимость элемента `<b class="header">` от 0.5 до 1
Tag('b.header').map(header => Fade.apply(header, 0.5, 1))

org.quickcorp.tools.effects.Radius

Округляет углы элемента.

Пример использования:
Radius.apply(element, радиусОт, радиусДо)

радиусОт и радиусДо — это числовые значения.

Пример:
// следующая строка округлит углы всех изображений в документе
Tag('img').map(element => Radius.apply(element, 0, 100))

org.quickcorp.tools.effects.Resize

Пример использования:
Resize.apply(element, масштабОт, масштабДо)

масштабОт и масштабДо — это числовые значения. Значение 1 соответствует обычному размеру, значение 2 — удвоенному размеру, значение между 0 и 1 — меньшему масштабу.

Пример:
// следующая строка создаст эффект зума вниз для каждого изображения в документе
Tag('img').map(element => Resize.apply(element, 2, 0))

// следующая строка создаст эффект зума вверх для каждого изображения в документе
Tag('img').map(element => Resize.apply(element, 0, 1))

// следующая строка создаст эффект зума вверх-вниз для каждого изображения в документе
Tag('img').map(element => Resize.apply(element, 2, 1))

org.quickcorp.tools.effects.WipeLeftСоздает эффект Wipe с левой стороны до центра элемента.

Использование:
WipeLeft.apply(element, scaleFrom, scaleTo)

scaleFrom и scaleTo — это числовые значения. Значение 1 соответствует обычному размеру, значение 2 — удвоенному размеру, значение между 0 и 1 — меньшему масштабу.

Пример
Tag('img').map(element => WipeLeft.apply(element, 0, 1))

org.quickcorp.tools.effects.WipeRight

Создает эффект Wipe с правой стороны до центра элемента.

Использование:
WipeRight.apply(element, scaleFrom, scaleTo)

scaleFrom и scaleTo — это числовые значения. Значение 1 соответствует обычному размеру, значение 2 — удвоенному размеру, значение между 0 и 1 — меньшему масштабу.

Пример
Tag('img').map(element => WipeRight.apply(element, 0, 1))

org.quickcorp.tools.effects.WipeUp

Создает эффект Wipe снизу вверх от центра элемента.

Использование:
WipeUp.apply(element, scaleFrom, scaleTo)

scaleFrom и scaleTo — это числовые значения. Значение 1 соответствует обычному размеру, значение 2 — удвоенному размеру, значение между 0 и 1 — меньшему масштабу.

Пример
Tag('img').map(element => WipeUp.apply(element, 0, 1))

org.quickcorp.tools.effects.WipeDown

Создает эффект Wipe сверху вниз от центра элемента.

Использование:
WipeDown.apply(element, scaleFrom, scaleTo)

scaleFrom и scaleTo — это числовые значения. Значение 1 соответствует обычному размеру, значение 2 — удвоенному размеру, значение между 0 и 1 — меньшему масштабу.##### Пример

Tag('img').map(element => WipeDown.apply(element, 0, 1))

Вспомогательные инструменты SDK

org.quickcorp.tools.canvas.CanvasTool

org.quickcorp.tools.layouts.BasicLayout

Виджеты SDK

Ниже приведены набор заранее определённых виджетов для общего использования.

org.quickcorp.views.GridView

Общее определение GridView для использования с сетками.

Сообщения локализации SDK

Двигатель локализации QCObjects позволяет вам определять пользовательские сообщения. Узнайте больше в этой статье в блоге разработчиков под названием Локализация для ваших прогрессивных веб-приложений.

org.quickcorp.i18n_messages.i18n_messages

Используется для вызова движка локализации.

Пример использования:
Class('i18n_messages_<custom lang>', i18n_messages, {
   ...
});
Пример
'use strict';
// файл: js/packages/org.quickcorp.i18n_messages.es.js
Package('org.quickcorp.i18n_messages.es', [
  Class('i18n_messages_es', i18n_messages, {
    messages: [
       // ... ваш словарь языка здесь
      {
         "en": "This is a paragraph",
         "es": "Esto es un párrafo"
      },
      {
         "en": "Welcome to my new app",
         "es": "Bienvenido a mi nueva app"
      }
    ]
  }),
  {
    _i18n_messages_es: New(i18n_messages_es)
  }
]);

Встроенный сервер HTTP/2 QCObjectsВстроенный сервер HTTP/2 QCObjects поможет вам протестировать ваше приложение в локальной среде перед развертыванием в продакшн. Для продакшн-среды рекомендуется использовать встроенный сервер HTTP/2 QCObjects под управлением Ubuntu 18.x или более поздней версии и NodeJS 12.x или более поздней версии.### Начало работы с QCObjects

Чтобы начать использование встроенного сервера HTTP/2 QCObjects, просто перейдите в путь вашего проекта и выполните следующую команду в вашей консоли:

> qcobjects launch mynewapp

или

> qcobjects-server

Это запустит сервер, который будет обслуживать файлы внутри текущей директории, используя встроенный сервер HTTP/2 с базовыми настройками.

Основные принципы многослойной архитектуры

QCObjects был спроектирован для работы в профессиональной среде. Есть множество способов и парадигм, которые вы можете использовать при определении своей архитектуры программного обеспечения. Одним из рекомендованных является использование многослойной или N-слоевой архитектуры. Преимущества многослойной (Multitier) или N-слоевой архитектуры заключаются в масштабируемости и надёжности систем, требующих большего воздействия и производительности. Для углубленного изучения этих концепций расширение данного справочного документа было бы излишним, но вы можете прочитать больше о данных концепциях по следующим внешним ссылкам (только для справки и изучения):

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

С помощью QCObjects вы можете писать свои микросервисы более элегантно, чисто и быстро.

Настройка бэкэнда в config.json

Вы также можете использовать config.json с бэкэндовой стороны для настроек и кастомизации бэкэнда, особенно полезно для создания маршрутов микросервисов.

Ниже приведён пример кастомизированного файла config.json, содержащий настройки бэкэнда:

{
  "documentRoot":"/home/qcobjects/projects/mynewapp/",
  "relativeImportPath":"js/packages/",
  "basePath":"/home/qcobjects/projects/mynewapp/",
  "projectPath":"/home/qcobjects/projects/mynewapp/",
  "domain":"mynewapp.qcobjects.com",
  "dataPath":"/etc/qcobjects/data/",
  "private-cert-pem":"/etc/letsencrypt/live/mynewapp.qcobjects.com/fullchain.pem",
  "private-key-pem":"/etc/letsencrypt/live/mynewapp.qcobjects.com/privkey.pem",
  "backend":{
    "routes":[
      {
        "path":"/createaccount",
        "microservice":"org.quickcorp.backend.signup",
        "responseHeaders":{}
      }
    ]
  }
}

Настройка маршрутов бэкэндаВнутри вашего файла config.json вы можете задать маршруты бэкенд-сервера для ваших микросервисов.

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

{
  "backend": {
    "routes": [
      {
        "path": "/createaccount",
        "microservice": "org.quickcorp.backend.signup"
      }
    ]
  }
}

При настройке маршрутов бэкенд-сервера сервер QCObjects HTTP2 Built-In будет знать, как обрабатывать запросы для каждого указанного пути. Для всех остальных путей, которые не определены в настройках маршрутов бэкенд-сервера, сервер будет использовать стандартное поведение — отвечать статическим файлом, если он существует. С этим в виду можно использовать QCObjects для управления и обслуживания статических файлов или динамически генерируемых файлов, когда это необходимо.

Класс микросервиса и пакет QCObjects

Когда вы задаете определение маршрута бэкенд-сервера, вам нужно указать пакет микросервиса. Этот пакет микросервиса представляет собой определение пакета в QCObjects, содержащего класс микросервиса, расширяющегося от класса BackendMicroservice, уже определенного в QCObjects.

Ниже приведен пример определения пакета микросервиса, записанного в файле org.quickcorp.backend.signup.js.

'use strict';
const fs = require('fs');
```Package('cl.quickcorp.backend.signup', [
  Class('Microservice', BackendMicroservice, {
    body: {
      "jsonrpc": "2.0",
      "result": "",
      "id": 1
    },
    saveToFile: function (filename, data) {
      logger.debug('Writing file: ' + filename);
      fs.writeFile(filename, data, (err) => {
        if (err) throw err;
        console.log('Файл был сохранён!');
      });
    },
    post: function (data) {
      let submittedDataPath = CONFIG.get('dataPath'); // этот параметр заполняется из qcobjects-server
      let filename = submittedDataPath + 'signup/signup' + Date.now().toString() + '.json';
      console.log('ПОЛУЧЕННЫЕ ДАННЫЕ: ' + data);
      this.saveToFile(filename, data);
    }
  })
]);Вышеуказанный микросервис сохраняет файл с полученными данными после POST-запроса и отвечает стандартным выходом JSON-RPC 2.0. Подробнее о спецификации JSON-RPC 2.0 читайте [здесь](https://www.jsonrpc.org/specification).

Сервер QCObjects HTTP2 Built-In вызывает метод `post()` определенного класса микросервиса только при получении POST-запроса на правильный путь, указанный в файле `config.json`, используя имя пакета как начальную точку отсчета. Чтобы позволить QCObjects понять и правильно выполнить ваши микросервисы, внутри пакета микросервиса требуется определение класса Microservice, а также это определение класса Microservice должно расширять класс BackendMicroservice, который является частью встроенных классов QCObjects.

### Генерация самоподписанного сертификата с помощью QCObjects

```shell
> qcobjects-createcert

Работа с HTTPS-сертификатом Let's Encrypt, Certbot и QCObjects

Быстрое руководство

Быстрое начало работы с PWA (Progressive Web App)

> qcobjects create --pwa mynewapp

Быстрое начало работы с AMP (Accelerated Mobile Pages)

> qcobjects create --amp mynewapp

Начало программирования

Шаг 1: Создайте основной файл импорта и назовите его как: cl.quickcorp.js. Разместите его в директории файлов packages/js/```javascript

"use strict"; /*

  • QuickCorp/QCObjects распространяется под лицензией
  • GNU Lesser General Public License v3.0
  • [LICENSE] (https://github.com/QuickCorp/QCObjects/blob/master/LICENSE.txt)
  • Условия этой копиродительской лицензии зависят от предоставления полного исходного кода лицензированных работ и модификаций под тем же лицензионным соглашением или GNU GPL v3. Авторские права и условия лицензий должны быть сохранены. Вкладчики предоставляют явное согласие на передачу прав на патент. Однако более крупная работа, использующая лицензированную работу через предоставленные лицензируемой работой интерфейсы, может быть распространена на других условиях и без исходного кода для более крупной работы.
  • Каждому разрешено делать и распространять точные копии этого лицензионного документа, но изменять его запрещается. */
Import('cl.quickcorp.model');
Import('cl.quickcorp.components');
Import('cl.quickcorp.controller');
Import('cl.quickcorp.view');

Package('cl.quickcorp', [
  Class('FormValidator', Object, {
  }),
]);## Шаг 2: Затем создайте некоторые сервисы, наследуемые классы, в файле js/packages/cl.quickcorp.services.js:

```javascript
".Strict";
/*
* QuickCorp/QCObjects распространяется под лицензией
* GNU Lesser General Public License v3.0
* [LICENSE](https://github.com/QuickCorp/QCObjects/blob/master/LICENSE.txt)
*
* Условия данной копyleft лицензии связаны с предоставлением полного исходного кода защищённых работ и модификаций под тем же лицензионным соглашением или GNU GPL v3. Авторские права и условия лицензии должны сохраняться. Вкладчики предоставляют явное согласие на передачу патентных прав. Однако более крупное программное обеспечение, использующее защищённое программное обеспечение через предоставленные им интерфейсы, может распространяться под другими условиями и без доступа к исходному коду для этого большего программного обеспечения.
*
* Все права защищены (C) 2015 Джейн Макучка, <correojean@gmail.com>
*
* Каждый имеет право делать и распространять точные копии данного лицензионного документа, но изменения в нём запрещены.
*/

Пакет('cl.quickcorp.service', [ Класс('FormSubmitService', JSONService, { имя: 'mySubmitService', внешний: true, закэшированный: false, метод: 'POST', сCredentials: false, url: 'https://api.github.com/orgs/QuickCorp/repos', new: function() { // сервис создан delete this.headers.charset; // не отправлять заголовок charset }, завершено: function(результат) { super('JSONService', 'завершено').call(this, результат); }, провал: function(результат) {

            // TODO отрицательный случай
             console.log("***** ОШИБКА");
         }
     })
 ])
```## Шаг 3: Теперь пришло время создать компоненты (cl.quickcorp.components.js)

```javascript
"strict";
/*
 * QuickCorp/QCObjects licensed under
 * GNU Lesser General Public License v3.0
 * [LICENSE](https://github.com/QuickCorp/QCObjects/blob/master/LICENSE.txt)
 *
 * The terms of this copyleft license depend on the provision of full source code for licensed works and modifications under the same license or GNU GPL v3. Copyrights and licensing conditions must be preserved. Contributors provide explicit consent to patent rights. However, a larger application using licensed code through provided interfaces may be distributed under different terms without the source code for that larger application.
 *
 * Copyright (C) 2015 Jean Macuchka, <correojean@gmail.com>
 *
 * Each person is permitted to make exact copies of this license document, but modifying it is prohibited.
 */
Package('cl.quickcorp.components', [
    Class('MyCustomComponent', Component, {
        name: 'mycustomcomponent',
        cached: false,
        controller: null,
        view: null,
        templateURI: ComponentURI({
            'COMPONENTS_BASE_PATH': Component.basePath,
            'NAME_COMPONENT': 'mycustomcomponent',
            'TEMPLATE_EXTENSION': 'tpl.html',
            'DEFAULT_TEMPLATE': 'default'
        })
    })
]);
```## Шаг 4: После того как вы выполнили объявление вышеуказанных компонентов, вам теперь следует написать ваши контроллеры (cl.quickcorp.controller.js)

```javascript
"use strict";
/*
 * QuickCorp/QCObjects распространяется под лицензией
 * GNU Lesser General Public License v3.0
 * [LICENSE](https://github.com/QuickCorp/QCObjects/blob/master/LICENSE.txt)
 *
 * Условия данной копировочной лицензии связаны с предоставлением полного исходного кода защищенных работ и модификаций под такую же лицензию или GNU GPL v3. Авторские права и условия лицензии должны быть сохранены. Вкладчики предоставляют явное разрешение на патентные права. Однако более крупное приложение, использующее защищенное приложение через предоставленные ему интерфейсы, может распространяться под другими условиями и без исходного кода для этого большего приложения.
 *
 * Всеобщие авторские права © 2cq 2015 Джон Макучка, <correojean@gmail.com>
 *
 * Каждому разрешено делать и распространять точные копии данного документа лицензии, но изменять его запрещается.
 */
"use strict";
Package('cl.quickcorp.controller', [
	Class('MainController', Controller, {
		_new_: function () {
			//TODO: Implement
			logger.debug('Элемент MainController инициализирован');
		}
	}),
	Class('MyAccountController', Controller, {
		component: null,
		done: function () {
			var controller = this;
```
```markdown
logger.debug('Элемент MyAccountController инициализирован');
this.component.body.setAttribute('loaded', true);
```},
_new_: function(o) {
    // TODO: Реализовать
    this.component = o.component;
    
}
]),
];
```

## Шаг 5: Для использования в HTML5 коде вам нужно выполнить некоторые настройки между тегами `<script>`:

```html
<script>
CONFIG.set('relativeImportPath', 'js/packages/');
CONFIG.set('componentsBasePath', 'templates/components/');
CONFIG.set('delayForReady', 1); // задержка перед выполнением первого события готовности, включает импорты
CONFIG.set('preserveComponentBodyTag', false); // не использовать тег <componentBody></componentBody>

Import('cl.quickcorp'); // это импортирует ваш основной файл: cl.quickcorp.js в путь к файлам js/packages/
</script>
```

# Инструмент командной строки QCObjects

## Использование

**qcobjects** [опции] [команда]

## Опции

   -V, --version                вывод номера версии
   -h, --help                   вывод справочной информации

## Команды

   **create** [опции] `<имя_приложения>`   Создает приложение с `<имя_приложения>`
   **publish** [опции] `<имя_приложения>`  Публикует приложение с `<имя_приложения>`
   **generate-sw** `<имя_приложения>`      Генерирует сервисный работник `<имя_приложения>`
   **launch** `<имя_приложения>`           Запускает приложение

## Использование:
   `$ qcobjects-cli [команда] --help`
   Для получения подробной информации о команде


## Лицензия
[![FOSSA Статус](https://app.fossa.com/api/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FQuickCorp%2FQCObjects?ref=badge_large)
```

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-qcobjects.git
git@api.gitlife.ru:oschina-mirror/mirrors-qcobjects.git
oschina-mirror
mirrors-qcobjects
mirrors-qcobjects
main