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

OSCHINA-MIRROR/mirrors-qcobjects

Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

logo

GitHub license FOSSA Status Documentation Status GitHub release GitHub stars npm version apm: version docker pulls Contributor Covenant CII Best Practices

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

QCObjects - Для написания изящного, чистого и быстрого кода | Product Hunt# QCObjects

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

QCObjects отмечен британским Herald как сегодняшний самый продвинутый фреймворк для современного программирования.

Этот документ является основной справочной документацией!

Этот репозиторий и 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 -->- Значение названия QCObjects (Не забудь про Q)

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

Принятые функции 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 использует [Intersection Observer API](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) (когда доступно), чтобы определить, является ли изображение lazy-src или src визуально полезным для отображения. Эффект ленивой загрузки заметен только в первый раз, когда PWA загружается. При последующих загрузках скорость загрузки значительно увеличивается, что затрудняет обнаружение изменений человеческим глазом. Однако эта функция значительно улучшает пользовательский опыт при низкой скорости интернет-соединения или при работе с очень большими изображениями. Эта функция является частью рекомендованных функций для PWA, описанных на [Mozzila Developers Network](https://developer.mozilla.org/) в статье о прогрессивной загрузке. Вы можете прочитать эту статью [здесь](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Loading). Если вы не хотите использовать ленивую загрузку для изображений, вы всегда можете оставить обычный способ загрузки, не добавляя атрибут **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 Status](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) для справки

# Авторские права
-----------

Авторские права (c) Jean Machuca и [QuickCorp](https://quickcorp.org) <info@quickcorp.cl>

# Демо
--------------

## Пример Progressive Web App (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 для манипуляции объектами canvas

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

```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
	    		});
    	</script>
    </head>
</html>
``````md
# Журнал разработки
--------------
Официальный [Журнал разработки QCObjects](https://devblog.qcobjects.org/) размещен на [Hashnode](https://hashnode.com/). Журнал разработки написан лично Jean Machuca, автором [QCObjects](https://qcobjects.com), который подробно объясняет лучшие практики и дает лучшие советы и хитрости для использования самых продвинутых функций QCObjects.
```# Ветвь
--------------
Пожалуйста, создайте ветку этого проекта или добавьте ссылку на этот проект в ваш файл README.md. Прочитайте файл LICENSE.txt перед использованием этого кода.

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

# Проверьте SDK QCObjects
----------------------------
Вы можете проверить [SDK QCObjects](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](https://qcobjects.dev/doc/img/QCObjects-Docker-Playground.gif)

## Скрипт однокомандной установки для Ubuntu 18.x

ВНИМАНИЕ: Выполните это только в свежей установке Ubuntu 18.x, не выполняйте в существующей среде производства. Вас могут попросить предоставить права sudo.

```shell
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 Windows

  1. Установите последнюю версию NodeJS для Windows с этой страницы
  2. Из командной строки установите qcobjects-cli с помощью npm
npm i qcobjects-cli -g
  1. Создайте директорию для вашего проекта```powershell md mynewproject && cd mynewproject
4.- Создайте новое Progressive Web Application QCObjects

```powershell
qcobjects create mynewproject --pwa

screenshot

Установка QCObjects в многоклудовой среде

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

DigitalOcean One-Click Droplet

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

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

AWS Amazon Machine Images (AMI)

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

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

  • Разрешения запуска, которые контролируют, какие AWS-аккаунты могут использовать AMI для запуска экземпляров.
  • Блок устройств, который указывает тома, которые нужно подключить к экземпляру при запуске.Начните создавать свой QCObjects AMI здесь

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

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

Начните создавать свой QCObjects Amazon Private Image здесь

Использование кода версии разработки напрямую в 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

<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/[VERSION]/QCObjects.js"></script>

Где [VERSION] — соответствующая последняя версия с использованием числового обозначения, например, чтобы использовать версию 2.1.420:```html

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

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

```html
<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 будет выполнен один раз после очереди функций asyncLoad и перед событием Ready.

Класс

Это НЕ определение класса ECMAScript 2015 (см. класс ECMAScript 2015 для справки).

Класс — это специальная функция, которая помогает вам объявить класс проще и совместимо. Она работает кросс-браузерно, и я надеюсь, что ECMA в будущем примет что-то подобное. Чтобы избежать путаницы, QCObjects использует "Class" вместо "class" (обратите внимание на Camel Case).

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

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"

QC_Append, метод append

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

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

Пример:

// Это создаст класс QCObjects с именем "canvas", расширяющий HTMLCanvasElement с свойством customAttr, имеющим значение "custom"
Class('canvas', HTMLCanvasElement, {
  customAttr: 'custom'
});
```// Это объявляет экземпляр canvas1 из класса canvas
let canvas1 = new(canvas, {
            width: 100,
            height: 100,
          });

// Это добавляет объект canvas1 в тело документа
document.body.append(canvas1);

Метод _super_

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

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


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

Пример:

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: 1, // это инициализирует значение в 1
    свойство2: 'какое-то значение'
});
console.log(новыйОбъект.метод2()); // это покажет число 1

### New

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

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

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

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

Пример:

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'))
/* Интересным моментом является ситуация, когда вы объявляете более одного класса с одним и тем же именем MyClass
* в разных пакетах, но с разными значениями по умолчанию и даже разными свойствами
*/
Package('org.quickcorp.package1', [
	Class('MyClass', {
		a: 1
	})
])
Package('org.quickcorp.package2', [
	Class('MyClass', {
		a: 2,
		b: 1
	})
])
// Последнее объявление MyClass будет тем, которое останется в очереди классов,
// поэтому ссылка MyClass в коде будет указывать на этот класс
console.log(MyClass === ClassFactory('MyClass')) // выведет 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, когда вам требуется полный контроль над областью при расширении классов.**Пример**

```javascript
// Когда вы обычно расширяете класс с помощью очереди класса, вы делаете следующее:
Class('MyExtendedClass', MyInheritClass, {
	extendedProp1: 'значение свойства',
	extendedProp2: 2
})
/* Но чтобы защитить область от ввода в заблуждение ссылкой, вы можете убедиться, что MyInheritClass
является тем, который вы хотите расширить, объявив его в пакете и затем расширив его
*/
Package('org.quickcorp.mypackage1', [
	Class('MyInheritClass', {
		sourceProp: 1
	})
])

// Следующий код является определением MyExtendedClass в другом пакете
// org.quickcorp.package2
// расширяет MyInheritClass с помощью ClassFactory для получения класса из исходного пакета
// org.quickcorp.mypackage1
Package('org.quickcorp.mypackage2', [
	Class('MyExtendedClass', ClassFactory('org.quickcorp.mypackage1.MyInheritClass'), {
		extendedProp1: 'значение свойства',
		extendedProp2: 2
	})
])

// это выведет число 1 (как наследуемое значение по умолчанию sourceProp)
console.log(New(MyExtendedClass).sourceProp)

_Crypt

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

Пример (1):

var _string = New(_Crypt, {string: 'hello world', key: 'some encryption md5 key'});
console.log(_string._encrypt());
console.log(_string._decrypt()); // расшифровывает зашифрованную строку до исходной

Пример (2):```javascript

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



### GLOBAL

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

#### Пример:

```javascript
GLOBAL.set('globalProperty1','значение в глобальной области');
var globalProperty1 = GLOBAL.get('globalProperty1');

CONFIG

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

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

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

Использование из файла config.json:

  1. Вам нужно указать сначала, что вы используете файл config.json, установив значение "useConfigService" в true
CONFIG.set('useConfigService',true); // использование config.json для настроек конфигурации
  1. После установки значения выше 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.

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

```javascript
Processor.setProcessor(processor)

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

Пример:

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

// файл: config.json
{
	"serviceURL":"$ENV(SERVICE_URL)",
	"host":"$SERVICE_HOST(SERVICE_URL)",
	"port":"$SERVICE_PORT(SERVICE_URL)"
}

Обработчики $SERVICE_HOST и $SERVICE_PORT не существуют. Чтобы определить их, вы должны использовать:

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

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 is present');
},()=>{return typeof someVar != 'undefined';});
// где condition это то, что я хочу дождаться

Пакет

Определяет пакет 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() и передав имя пакета в качестве аргумента.


### Импорт
Импортирует пакет из другого JS файла

#### Использование:
```javascript
Import (packagename,[ready],[external]);

Где packagename это имя пакета, ready это функция, которая будет выполнена после загрузки пакета, а external это булево значение, которое указывает, находится ли JS файл в той же области или это внешний ресурс.

Пример (1):

Import('org.quickcorp.main');

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

Пример (2):

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

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

ЗАМЕЧАНИЕ: В обоих вышеуказанных примерах вы не указали расширение ".js". Это используется по умолчанию и не может быть изменено по соображениям безопасности.### Экспорт Устанавливает символ (переменную или функцию) в глобальном пространстве имен.

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

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


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

Cast

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

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

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

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

Пример:

Class('MyOwnClass',{
  prop1:'1',
  prop2:2
});

let obj = document.createElement('div').Cast(MyOwnClass);

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

Tag

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

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

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

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

Пример:```html

<title>Демо</title> <script type="text/javascript" src="https://cdn.qcobjects.dev/QCObjects.js"></script>

Привет, мир

<script> Ready(()=>{ Tag('.myselector > p').map((element)=>{ element.innerHTML = 'Привет, мир! Как дела?'; }); }); </script> ```

В вышеприведенном коде элементом параграфом создается элемент внутри div с CSS-классом myselector, а затем он динамически изменяется с помощью функции Tag библиотеки QCObjects. Если вы знакомы с фреймворками для работы с селекторами, такими как jQuery, вы оцените эту функцию.

Ready

Присвойте функцию для выполнения после завершения всех действий QCObjects и события window.onload. Используйте его для предотвращения ошибок "неопределенный" DOM-объект.

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

Ready(()=>{
  // Мой код инициализации здесь!
});

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

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

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

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

Свойства**[Component].domain**

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

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

Замечание: Если вы хотите изменить базовый путь компонента, вам нужно использовать CONFIG.set('componentsBasePath','новый путь относительно домена') в вашем коде инициализации.

[Component].templateURI Это строка, представляющая URI-шаблона компонента относительно домена. Когда это свойство установлено, компонент загружает шаблон и добавляет внутренний контент в дочерние элементы тела как часть DOM. Для установки этого свойства рекомендуется использовать функцию помощника ComponentURI.

[Component].tplsource Это строка, представляющая источник загрузки шаблона. Это может быть "default" или "none". Значение "default" говорит QCObjects загружать шаблон из содержимого templateURI. Значение "none" говорит QCObjects не загружать шаблон откуда-либо.

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

[Component].name Это строка, представляющая имя компонента. Имя компонента может быть любым алфавитно-цифровым значением, которое идентифицирует тип компонента. Это будет использоваться внутренне ComponentURI для построения нормализованного URI-шаблона компонента.[Компонент].method Это строка, представляющая HTTP или HTTPS метод. По умолчанию каждый компонент настроен для использования метода "GET". В большинстве случаев вам не нужно изменять это свойство.[Компонент].data Это объект, представляющий данные компонента. При загрузке шаблона QCObjects получает каждое свойство объекта data и связывает его с меткой шаблона, представляющей то же свойство внутри содержимого шаблона между двойными фигурными скобками (например: {{prop1}} в содержимом шаблона будет представлять data.prop1 в экземпляре компонента). ЗАМЕЧАНИЕ: Для обновления связей данных необходимо пересоздать компонент (см. использование метода [Компонент].rebuild() для получения дополнительной информации).[Компонент].reload Логическое значение, которое указывает QCObjects, нужно ли принудительно перезагружать содержимое компонента из шаблона или нет. Если значение равно true, содержимое шаблона заменит текущие дочерние элементы DOM тела компонента. Если значение равно false, содержимое шаблона будет добавлено после последнего дочернего элемента тела компонента.[Компонент].cached Логическое значение, которое указывает QCObjects, нужно ли кэшировать компонент или нет. Когда компонент кэширован, содержимое шаблона, загруженное из templateURI, загружается только один раз. Вы можете установить это свойство либо как статическое свойство класса Компонента для установки значения по умолчанию для каждого последующего экземпляра компонента, либо установить индивидуальное значение свойства для каждого определения компонента. В мире, где производительность имеет значение, необходимость предоставления большей гибкости поведению кэширования важна как никогда.[Компонент].routingWay Возвращает строку, представляющую способ маршрутизации. Значение может быть "hash", "pathname" или "search". ЗАМЕЧАНИЕ: Для изменения способа маршрутизации каждого компонента рекомендуется использовать CONFIG.set('routingWay', 'значение допустимого способа маршрутизации') в вашем коде инициализации.

[Компонент].validRoutingWays Возвращает список, представляющий допустимые способы маршрутизации. QCObjects использует это для внутренней проверки способа маршрутизации, использованного для построения маршрутизации компонента.

[Компонент].routingNodes Возвращает объект NodeList, представляющий список узлов, загруженных построителем маршрутизации компонента.

[Компонент].routings Возвращает список маршрутизаций компонента, построенных при создании компонента.

[Компонент].routingPath Возвращает строку, представляющую текущий путь маршрутизации.

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

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

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

Методы

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

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

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

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

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

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

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

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

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

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

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

Атрибут name

<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>
Атрибут cached

<component cached> Устанавливает свойство кэширования для экземпляра компонента.

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

Использование:
<component name="name_of_component" cached="true"></component>
```##### Объявление свойства данных
 **`<component data-property1 data-property2 ...>`**
Устанавливает статическое значение свойства для объекта данных в экземпляре компонента.

**Замечание:** Объявление свойства данных тега было разработано с целью предоставить простой способ имитации динамического компонента с привязкой шаблонов. Не используйте его, полагая, что это двустороннее привязывание данных. Хотя вы можете получить поведение двустороннего привязывания данных, обращаясь к объекту данных из экземпляра компонента, это не то же самое для тега компонента. Объявление свойства данных в тегах компонентов является только односторонним привязыванием данных из-за архитектуры дерева компонентов.##### Атрибут controllerClass
**`<component controllerClass>`**
Определяет пользовательский класс контроллера для экземпляра компонента

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

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

Использование:
<component name="name_of_component" viewClass="ViewClassName"></component>
Атрибут componentClass

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

Использование:
<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(шаблонURI); // это выведет что-то вроде "templates/components/main.tpl.html" в зависимости от ваших настроек CONFIG

componentLoader

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

Использование:
[Promise] componentLoader(экземплярКомпонента, загрузитьАсинхронно)

Где экземплярКомпонента — это экземпляр компонента, созданный с помощью _New(КлассОпределенияКомпонента)

Пример:
componentLoader(экземплярКомпонента, загрузитьАсинхронно).then(
  (успешныйСтандартныйОтвет) => {
    // успешная загрузка компонента
    var запрос = успешныйСтандартныйОтвет.запрос;
    var компонент = успешныйСтандартныйОтвет.компонент;
  }, (неуспешныйСтандартныйОтвет) => {
    // неудачная загрузка компонента
    var компонент = неуспешныйСтандартныйОтвет.компонент;
  });
```#### buildComponents
Перестраивает каждый компонент, являющийся дочерним элементом элемента DOM, который владеет методом. В большинстве случаев вам не потребуется вызывать buildComponents для построения или перестроения каждого компонента в DOM. Это автоматически вызывается QCObjects, когда это необходимо.##### Использование:
```javascript
[элемент].buildComponents()
Пример:
document.buildComponents()

Controller

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

View

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

VO

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

Service

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

Свойства

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

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

[Service].url Это строка, представляющая полный URL-адрес сервиса. Он может быть абсолютным или относительным к basePath, когда это применимо. Это также может быть внешний URL.

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

[Service].method Является строкой, представляющей HTTP или HTTPS метод. Возможные значения: "GET", "POST", "PUT", ... и другие, которые принимаются REST-сервисами.[Service].data Является объектом, представляющим данные сервиса. Когда QCObjects загружает сервис, он получает ответ и интерпретирует его как шаблон. Поэтому, как только получен ответ сервиса, каждое свойство объекта данных будет связано с меткой шаблона, представляющей то же свойство внутри содержимого шаблона между двойными фигурными скобками (например: {{prop1}} в содержимом шаблона будет представлять data.prop1 в экземпляре сервиса).[Service].cached Является булевым значением, которое указывает QCObjects, нужно ли кэшировать ответ сервиса или нет. Когда сервис кэшируется, содержимое шаблона, загруженное с URL сервиса, будет загружено только один раз. Вам нужно установить это значение в false для каждого экземпляра сервиса, чтобы гарантировать, что сервис загружается из ресурса, а не из кэша.

Методы

[Service].set('prop', value) Устанавливает значение для свойства сервиса.

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

serviceLoader

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

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

[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 загружает сервис, он получает ответ и интерпретирует его как шаблон. Поэтому, как только получен ответ сервиса, каждое свойство объекта data будет связано с меткой шаблона, представляющей то же свойство внутри содержимого шаблона между двойными фигурными скобками (например: {{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

Пример:

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

Класс SourceJS

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

Пример:

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 для эмуляции создания потоков, что позволяет эффективнее управлять параллельным выполнением в реальном времени.

Пример:

Timer.thread({
	duration: 300, // миллисекунды
	timing: function (timeFraction, elapsed) {
		return timeFraction; // можно изменить эту строку для возврата пользовательской функции
	},
	intervalInterceptor: function (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 my_unique_list = [0, 1, 2, 1, 2].unique();
// результат: my_unique_list = [0, 1, 2]

[ArrayList или Array].table

Это предназначено только для использования в shell-скриптах. Показывает таблицу значений в списке.

["a", "b", "c", "d"].table();
// будет показывать
┌─────────┬────────┐
 (index)  Values 
├─────────┼────────┤
    0      'a'   
    1      'b'   
    2      'c'   
    3      'd'   
└─────────┴────────┘
```### [ArrayList или Array].sort

Сортирует элементы массива или списка.

```javascript
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, для создания списка диапазона. Вы можете использовать её вместе с ArrayList.matrix, ArrayList.matrix2d и ArrayList.matrix3d для генерации сложных диапазонов матриц.
#### Использование

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


```javascript
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, который позволяет внедрять общее поведение поля формы в ваши компоненты. Он имеет функцию обратной привязки данных для обнаружения значений полей DOM внутри формы и присваивания их значениям данных вашего компонента. Таким образом, вы не теряете производительность, используя устаревшую двухстороннюю привязку данных на основе наблюдаемых значений. Для реализации этого продвинутого поведения вам нужно выполнить следующие шаги:

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

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

<!-- Где вы размещаете компонент -->
<component name="myform" componentClass="FormField"></component>
<!-- template: 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>Password</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 по умолчанию имеет <input> DOM-элемент в качестве тела компонента. В то время как 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, необходимого для Swagger UI API. Узнайте больше в этой статье блога разработчиков 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="logo" src="./img/logo-qcobjects-white.svg"></img>
</component>
<!-- Затем вы можете поместить ваш основной компонент как обычно -->
<component name="main" cached="true" controllerClass="MainController">
</component>

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

org.quickcorp.controllers.GridController

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

org.quickcorp.controllers.DataGridControllerDataGridController будет использовать данные вашего компонента и отображать набор подкомпонентов для заполнения.

Это обычно используется для отображения динамического списка компонентов. Он использует значение атрибута 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"
	}
})
<!-- template: card.tpl.html -->
<img src="{{profilePicture}}"/>
<h3>{{name}}</h3>
<p>{{email}}</p>

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

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

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

  • Присвоение serviceClass
  • Определение formSettings
  • Присвоение или написание валидаций полей
[FormController].serviceClass

Это строковое имя определения класса. FormController загрузит этот класс с помощью функции помощника 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.```javascript // Сначала определим сервисный класс, который будет вызван при отправке. 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); } })

// Чтобы безопасно расширить 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: () => {
			return function (fieldName, dataValue, element) {
				return (dataValue !== '') ? true : false;
			}
		}
	},
	defaultController: null,
	_new_: function (o) {
		o.serviceClass = this.serviceClass;
		o.formSettings = this.formSettings;
		o.validations = this.validations;
		// здесь мы инициализируем defaultController с новым FormController
		// передаём объект o, который приходит из процесса построения компонентов.
		this.defaultController = New(FormController, o);
	},
	done: function () {
		// определяем пользовательский done callback функцию для внедрения пользовательского поведения, а также вызова поведения defaultController
		logger.debugEnabled = true;
		var controller = this.defaultController;
		try {
			controller.done.call(controller);
		} catch (e) {
			logger.debug('Не удалось выполнить стандартное поведение');
		}
	}
})
``````html
<!-- Теневой компонент для отображения формы регистрации -->
<!-- template: форма-регистрации.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 -->
 <! -- template: signup. tpl. html -->
 <component name="signup-form" shadowed="true" controllerClass="SignupFormController">
   <h1 slot="title">Форма регистрации</h1>
   <p slot="subtitle">Пожалуйста, заполните эту форму для запроса котировок.</p>
   <label slot="field-control" id="name_label" for="name"><b>&#x1F9D1; Полное имя</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>&#x1F4E7; Электронная почта</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>&#x1F4DD; Комментарий</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='/#'" role="button" tabindex="-1" type="button" class="cancelbtn"><p>Отмена</p></button>
 	</div>
 </component>	    <button aria-label="Отправить" role="button" tabindex="-1" type="button" class="signupbtn submit"><p>Отправить</p></button>
 	</div>
 </component>
 ```#### org.quickcorp.controllers.SwaggerUIController

Используется для внедрения DOM Swagger UI, необходимого для API Swagger UI. Узнайте больше в этой статье блога разработчиков QCObjects под названием [Работа с 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**, подробнее [здесь](https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#animation-frames)#### org.quickcorp.tools.effects.Move

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

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

```javascript
Move.apply(element, xfrom, yfrom, xto, yto)
```

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

```javascript
// Следующая строка переместит все изображения с (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 в исходное положение объекта.

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

```javascript
MoveXInFromLeft.apply(element)
```

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

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

#### org.quickcorp.tools.effects.MoveYInFromBottom

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

##### Использование:
```javascript
MoveYInFromBottom.apply(element)
```

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

#### org.quickcorp.tools.effects.MoveYInFromTop

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

##### Использование:
```javascript
MoveYInFromTop.apply(element)
```

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

#### org.quickcorp.tools.effects.RotateX

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

##### Использование:
```javascript
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.

##### Использование:
```javascript
RotateY.apply(element, angleFrom, angleTo)
```

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

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

#### org.quickcorp.tools.effects.RotateZ

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

##### Использование:
```javascript
RotateZ.apply(element, angleFrom, angleTo)
```

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

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

#### org.quickcorp.tools.effects.Rotate

Поворачивает объект вокруг осей X, Y и Z. Все оси будут поворачиваться параллельно, создавая визуальное 3D-эффект.

##### Использование:
```javascript
Rotate.apply(element, angleFrom, angleTo)
```

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

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

#### org.quickcorp.tools.effects.Fade

Создает эффект плавного затемнения элемента, уменьшая его прозрачность.

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

```javascript
Fade.apply(element, alphaFrom, alphaTo)
```

**alphaFrom** и **alphaTo**  числа от 0 до 1.

```javascript
// следующая строка плавно затемнит элемент <b class="header"> от 0.5 (средняя видимость) до 1 (полная видимость)
Tag('b.header').map(header => Fade.apply(header, 0.5, 1));
```#### org.quickcorp.tools.effects.Radius

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

##### Использование:
```javascript
Radius.apply(element, radiusFrom, radiusTo)
```

**radiusFrom** и **radiusTo**  числовые значения.

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

#### org.quickcorp.tools.effects.Resize

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

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

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

```javascript
// следующая строка создаст эффект уменьшения масштаба для каждого изображения в документе
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 с левой стороны к началу элемента.

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

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

##### Пример

```javascript
Tag('img').map(element => WipeLeft.apply(element, 0, 1))
```#### org.quickcorp.tools.effects.WipeRight
Создает эффект Wipe с правой стороны к началу элемента.

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

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

##### Пример

```javascript
Tag('img').map(element => WipeRight.apply(element, 0, 1))
```

#### org.quickcorp.tools.effects.WipeUp
Создает эффект Wipe снизу вверх к началу элемента.

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

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

##### Пример

```javascript
Tag('img').map(element => WipeUp.apply(element, 0, 1))
```

#### org.quickcorp.tools.effects.WipeDown
Создает эффект Wipe сверху вниз к началу элемента.

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

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

##### Пример

```javascript
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 для использования с сетками.### Сообщения i18n SDK

Двигатель i18n QCObjects позволяет вам определять пользовательские сообщения. Узнайте больше в этой статье в блоге разработчиков под названием [i18n Международная локализация для ваших Progressive Web Apps](https://devblog.qcobjects.org/i18n-internationalisation-for-your-progressive-web-apps-ck90h4qz301ca7vs1ue7joopu)

#### org.quickcorp.i18n_messages.i18n_messages

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

##### Пример использования:
```javascript
  Class('i18n_messages_<custom_lang>', i18n_messages,{
		...
	})
```

##### Пример
```javascript
'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 и автоматически привязывает его к пакету
    _i18n_messages_es: New(i18n_messages_es)
  }
]);
```

## Встроенный сервер HTTP2 QCObjects

Встроенный сервер HTTP2 QCObjects поможет вам протестировать ваше приложение в локальной среде перед развертыванием в среде производства. Для среды производства рекомендуется использовать встроенный сервер HTTP2 QCObjects под Ubuntu 18.x или новее и NodeJS 12.x или новее.

### Начало работы с QCObjects

Чтобы начать использовать встроенный сервер HTTP2 QCObjects, просто перейдите в путь к вашему проекту и выполните следующую команду в вашей оболочке bash:```shell
> qcobjects launch mynewapp
```

или

```
> qcobjects-server
```

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

### Принципы многоуровневой (N-Tier) архитектуры

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

- [Многоуровневая архитектура](https://en.m.wikipedia.org/wiki/Multitier_architecture)
- [Трехуровневая архитектура](https://www.tonymarston.net/php-mysql/3-tier-architecture.html)
- [Многоуровневое приложение](https://www.techopedia.com/definition/23599/multi-tier-application)
- [N-уровневая архитектура: концепции и советы](https://www.guru99.com/n-tier-architecture-system-concepts-tips.html)


### Принципы микросервисовОсновная цель микросервиса заключается в том, чтобы вы могли упаковать фрагмент функциональности backend в код, который может быть вызван удаленно с другого backend или frontend терминала. В основном вы можете разделить высокий уровень сервиса backend на множество маленьких микросервисов, которые могут выполнить задачу. Существует тысячи хороших примеров использования этого шаблона. Вы можете прочитать больше о концепции микросервисов по следующим внешним ссылкам (только для справки и изучения):- [Шаблоны микросервисов](https://microservices.io)
- [Микросервисы на Википедии](https://en.wikipedia.org/wiki/Microservices)

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


### Настройки backend в config.json

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

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

```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":{}
      }
    ]
  }
}
```

### Маршрутизация backend

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

```json
{
  "backend":{
    "routes":[
      {
        "path":"/createaccount",
        "microservice":"org.quickcorp.backend.signup"
      }
    ]
  }
}
```Когда вы задаёте маршруты backend, встроенный сервер HTTP/2 QCObjects будет знать, как обрабатывать запросы для каждого заданного пути. Для всех других путей, которые не определены в настройках маршрутов backend, сервер будет обрабатывать запросы с использованием стандартного поведения, то есть отвечая статическим файлом, если он существует.

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

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

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

```javascript
'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('The file has been saved!');
      });
    },
    post: function (data) {
      let submittedDataPath = CONFIG.get('dataPath'); // this is filled out from qcobjects-server
      let filename = submittedDataPath + 'signup/signup' + Date.now().toString() + '.json';
      console.log('DATA RECEIVED: ' + data);
      this.saveToFile(filename, data);
    }
  })
]);

```

Вышеупомянутый микросервис сохраняет файл с данными, полученными от POST-запроса, и отвечает стандартом JSON RPC 2.0. Подробнее о спецификации JSON RPC 2.0 можно прочитать [здесь](https://www.jsonrpc.org/specification)Встроенный сервер HTTP2 QCObjects будет вызывать метод post() определённого класса микросервиса только при получении POST-запроса на правильный путь, заданный в config.json, с указанием имени пакета как начальной точки сопоставления. Чтобы позволить QCObjects понимать и правильно выполнять ваши микросервисы, внутри пакета микросервиса требуется определение класса Microservice, а также определение класса Microservice должно расширять класс BackendMicroservice, который является частью встроенных классов QCObjects.### Генерация самоподписного сертификата с помощью QCObjects

```shell
> qcobjects-createcert
```

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

# Быстрый старт

### Быстрый старт вашего PWA (Progressive Web App)

```shell
> qcobjects create --pwa mynewapp
```

### Быстрый старт вашего AMP (Accelerated Mobile Page)

```shell
> 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 GPLv3. Авторские права и условия лицензии должны быть сохранены. Вкладчики предоставляют явное разрешение на патентные права. Однако более крупное приложение, использующее лицензированные работы через предоставляемые лицензированными работами интерфейсы, может быть распространено на других условиях и без исходного кода для более крупного приложения.
*
* Copyright (C) 2015 Jean Machuca, <correojean@gmail.com>
*
* Каждому разрешено копировать и распространять точные копии этого лицензионного соглашения, но изменять его запрещено.
*/


Import ('external/libs');
Import ('cl.quickcorp.model');
Import ('cl.quickcorp.components');
Import ('cl.quickcorp.controller');
Import ('cl.quickcorp.view');
``````markdown
Package('cl.quickcorp',[
  Class('FormValidator',Object,{

  }),
]);

```

## Шаг 2: Затем создайте некоторые сервисы, наследующие классы, в файле js/packages/cl.quickcorp.services.js :```javascript
"use strict";
/*
* QuickCorp/QCObjects распространяется под лицензией
* GNU Lesser General Public License v3.0
* [LICENSE] (https://github.com/QuickCorp/QCObjects/blob/master/LICENSE.txt)
*
* Условия данной копyleft лицензии связаны с предоставлением полного исходного кода
* лицензированных работ и модификаций под той же лицензией или GNU GPLv3.
* Авторские права и уведомления о лицензии должны быть сохранены.
* Участники предоставляют явное разрешение на патентные права.
* Однако более крупная работа, использующая лицензированную работу через интерфейсы,
* предоставляемые лицензированной работой, может распространяться на других условиях
* и без исходного кода для более крупной работы.
*
* Copyright (C) 2bk 2015 Jean Machuca, <correojean@gmail.com>
*
* Каждому разрешается копировать и распространять точные копии этого
* документа лицензии, но изменять его запрещено.
*/
``````package(cl.quickcorp.service,[
	Class('FormSubmitService',JSONService,{
	    name:'mySubmitService',
	    external:true,
	    cached:false,
	    method:'POST',
	    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);
	    },
			fail: function(result) {
	      //TODO отрицательный случай
	      console.log("***** ОШИБКА");
	    }
  })
])
```## Шаг 3: Теперь настало время создать компоненты (cl.quickcorp.components.js)

```javascript
"строго";
/*
* QuickCorp/QCObjects лицензировано под
* GNU Lesser General Public License v3.0
* [LICENSE] (https://github.com/QuickCorp/QCObjects/blob/master/LICENSE.txt)
*
* Условия этого копиродительского лицензирования зависят от предоставления полного исходного кода лицензированных работ и модификаций под тем же лицензированием или GNU GPLv3. Заявления авторства и лицензирования должны быть сохранены. Провайдеры предоставляют явное разрешение на патентные права. Однако более крупная работа, использующая лицензированную работу через интерфейсы, предоставленные лицензированной работой, может быть распространена на других условиях и без исходного кода для более крупной работы.
*
* Авторское право (C) 2015 Jean Machuca, <correojean@gmail.com>
*
* Каждому разрешено копировать и распространять точные копии этого лицензионного документа, но изменять его запрещено.
*/
Package('cl.quickcorp.components',[
	Класс('MyCustomComponent', Component, {
	  name: 'mycustomcomponent',
	  cached: false,
	  controller: null,
	  view: null,
		templateURI: ComponentURI({
			'COMPONENTS_BASE_PATH': Component.basePath,
			'COMPONENT_NAME': 'mycustomcomponent',
			'TPLEXTENSION': 'tpl.html',
			'TPL_SOURCE': '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)
*
* Условия данной копyleft лицензии связаны с предоставлением полного исходного кода лицензированных работ и модификаций под той же лицензией или GNU GPLv3. Заявления авторства и лицензии должны быть сохранены. Участники предоставляют явное разрешение на патентные права. Однако более крупное приложение, использующее лицензированное приложение через интерфейсы, предоставленные лицензированным приложением, может распространяться на других условиях и без исходного кода для более крупного приложения.
*
* Copyright (C) 2cq 2015 Jean Machuca, <correojean@gmail.com>
*
* Каждый имеет право копировать и распространять точные копии этого лицензионного документа, но изменять его нельзя.
*/
"use strict";
Package('cl.quickcorp.controller',[
	Class('MainController',Controller,{
		_new_:function (){
			//TODO: Implement
			logger.debug('MainController Element Initialized');
		}
	}),
	Class('MyAccountController',Controller,{
		component: null,
		done:function (){
			var controller = this;
``````markdown
## Шаг 5: Для использования в коде HTML5 вам нужно выполнить некоторые настройки между тегами `<script>`:```html
<script>
CONFIG.set('relativeImportPath','js/packages/');
CONFIG.set('componentsBasePath','templates/components/');
CONFIG.set('delayForReady',1); // задержка ожидания перед выполнением первого события ready, включая импорты
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** ```<имя_приложения>```      Генерирует сервисный worker ```<имя_приложения>```
   **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 )

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

Введение

QCObjects — это открытый исходный код на основе JavaScript, цель которого — упростить перенос всего, что реализовано в модели MVC, в область чистого JavaScript. Развернуть Свернуть
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
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