WEB start

Компьютеры. Интернет. Профессиональное обучение. 055-966-10-17

hit 
counter

Наши преимущества

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


Регистрация на сайте

Angular

  • Angular 6

    Angular

    Angular - это фреймворк, разработанный Google для создания клиентских (frontend WEB development) приложений. Прежде всего он предназначен для разработки SPA - проектов (Single Page Application), то есть одностраничных приложений. В этом плане Angular является наследником другого фреймворка AngularJS. В то же время Angular, начиная с версии 2, это не новая версия AngularJS, а принципиально новый фреймворк.

    Последняя версия Angular на момент написания - Angular 6. Официальный репозиторий фреймворка на гитхаб: https://github.com/angular/angular.

    Одной из ключевых особенностей Angular является то, что он использует в качестве языка программирования TypeScript. Можно писать приложения на Angular с помощью таких языков как Dart, ECMAScript или JavaScript. TypeScript является основным языком для Angular.

    Язык TypeScript - это надмножество языка ECMAScript 6 (также известной как ECMAScript 2015, ES2015), которое компилируется в обычный код на JavaScript (ES5) и широко поддерживается современными ОС.

    На настоящий момент браузеры не имеют встроенной поддержки ни TypeScript, ни ECMAScript 6, поэтому для публикации на сервеере код должен быть преобразован в код на JavaScript, поддерживаемый всеми браузерами.

    Установка Angular

    https://angular.io/guide/setup#windows

    NodeJS

    Установка

    NodeJS ( Node.js® - это среда выполнения для языка JavaScript, построенная на платформе JavaScript V8 для Chrome. https://nodejs.org/en/)

    Node.js позволяет запускать JavaScript-код вне браузера.

    Чтобы JavaScript код выполнился вне браузера (на backend), он должен быть интерпретирован и выполнен. Именно это и делает Node.js. Для этого он использует движок V8 VM от Google — ту же самую среду исполнения для JavaScript, которую использует браузер Google Chrome.

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

    Так, например, для 32 bit Windows нужен файл: node-v8.9.4-x86.msi . Программа установки NodeJS для Windows одной из опций предлагает поставить также и npn.

    Проверить версию

    node -v npm

    (npm - это менеджер пакетов для JavaScript и самый большой реестр программного обеспечения https://www.npmjs.com/)

    Если не поставили вместе с NodeJS, то скачать по ссылке https://nodejs.org/en/download/ и поставить дополнительно.

    Некоторые команды

    npm -v

    проверить версию

    p> npm list strong>

    получить перечень локально установленны пакетов

    npm list -g

    список глобально установленных пакетов

    Angular CLI

    Наиболее популярный инструмент для управления пректами Angular.

    https://cli.angular.io/

    На github:

    https://github.com/angular/angular-cli

    установить cli

    npm install -g @angular/cli

    удалить cli

    npm uninstall -g angular-cli

    npm cache clean

    npm cache clean --force

    проверить установленную версию

    ng --version

    Редактор кода

    Для редактирования проектов на Angular удобно пользоваться, например:

    Visual Studio Code

    Notepad++

    Новый проект

    Запустить консоль NodeJS

    Перейти в папку с проектами Angular и запустить создание нового - project1 командой:

    ng new project1

    Перейти в папку созданного проекта

    cd project1

    CLI автоматически создаёт начальную структуру папок и файлов проекта.

    В папке ./src/app находятся, в частности:

    • app.component.ts - первый Angular - компонент, корневой, он называется app-root
    • app.module.ts - исполняемый модуль
    • app.component.css - стили
    • app.component.html - шаблон HTML для вывода в окно браузера

    Запустить проект

    ng serve

    или, указав другой порт и директиву открыть сразу проект в браузере: 

    ng serve --port 3000 --open

    Открыть запущенный проект в браузере

    http://localhost:4200 (или, соответственно http://localhost:3000)

    Редактировать проект

    Файлы запущенного проекта можно редактировать в любом редакторе кодов (например: Notepad++). При сохранении изменений проект автоматически перезапускается и в окне браузера сразу отражаются изменения.

    Отредактируем файл шаблона корневого компонента нашего приложения (), заменим его на:

    <h1> Название проекта: {{ title }}! </h1> <h2> Наш первый проект с Angular 5 </h2>

    Сгенерировать проект для публикации

    ng build --prod

    Проект для публикации (HTML, CSS, JavaScript) по умолчанию создастся в папке dist

    Все команды ng (Angular):

    Wiki https://github.com/angular/angular-cli/wiki

    PDF https://cli.angular.io/reference.pdf

    Angular компоненты (Components)

    Основной составляющий блок проекта на Angular - компонент.

    Создаём новый компонент (Angular component)

    Создаём компонент с именем comp1 в паке существующего проекта

    ng generate component comp1

    По завершении команды в папке app проекта добавилась папка нашего нового компонента - src/app/comp1.

    В файл app.module.ts добавилась строки описания нашего компонента: 

    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { Comp1Component } from './comp1/comp1.component'; @NgModule({ declarations: [ AppComponent, Comp1Component ], imports: [ BrowserModule ], providers: [], bootstrap: [ AppComponent] }) export class AppModule { }

    По-умолчанию создался компонент с селектором: app-comp1. Используя этот селектор можно добавить новый компонент в наше приложение. Для этого в файле с шаблоном нашего приложения (app.component.html) добавим строки:

    Он примет вид:

    <div style="text-align:center"> <h1> Название проекта: {{ title }}! </h1> <H1> Наш первый проект с Angular 5 </H1> <app-comp1> </app-comp1>


    Шаблон нового компонента находится в его файле с именем:

    src\app\comp1\comp1.component.html

    Отредактируем его, вставив строки:

    <h2> Первый компонент! </h2>

    Запустить наше приложение с новым компонентом, проверить работу:

    ng serve


    Angular 5 web-start.top

    Структура компонента Angular

    Компонет состоит из 3-х секций:

    1. директива - import
    2. декоратор
    3. директива export

    Импортируем из библиотеки '@angular/core' необходимые модули:

    import { Component, OnInit } from '@angular/core';

    Некоторые компоненты могут содержать множество директив import

    Декоратор компонента позволяет менять некоторые свойства нашего компонента (метаданные).

    Приведённый ниже декоратор задаёт свойства компонента (selector, templateUrl, styleUrls).

    @Component({ selector: 'app-comp1', templateUrl: './comp1.component.html', styleUrls: ['./comp1.component.css'] })

    selector - имя тега, использование которого инициирует наш компонент.

    templateUrl - шаблон HTML (может быть именем файла или встроенным набором HTML - свойство template )

    styleUrls - листы стилей (список файлов или встроенный - inline набор описаний стилей - свойство styles )

    В директиве export описаны свойства и методы класса-компонента, которые будут доступны другим компонентам приложения

    export class Comp1Component implements OnInit { public title ; constructor() { } ngOnInit() { this.title = 'Первый компонент запущен.' } }  


    Файл компонента - программа на Typescript :

    import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-comp1', templateUrl: './comp1.component.html', styleUrls: ['./comp1.component.css'] }) export class Comp1Component implements OnInit { public title ; constructor() { } ngOnInit() { this.title = 'Первый компонент запущен.' } }


    Angular 5 web-start.top

    Шаблоны Angular (Angular templates)

    Создадим новый проект (app-my-first-component) и посмотрим, как работать с шаблонами и стилями.

    Встроенные и внешние шаблоны (inline & external Angular templates)

    Параметры templateUrl и styleUrls , заданные в декораторе, определяют путь к внешним файлам, содержащим шаблон.

    Параметры template и style описывают встроенный шаблон (соответственно HTML и CSS ). Если необходимо использовать несколько строк для inline описаний, то вместо ограничителя строки - кавычка (') используется ограничитель строки - backtick (`) 

    Например

    template: '<h1>Inline HTML template</h1>',

    Или:

    import { Component} from '@angular/core'; @Component({ selector: 'app-my-first-component', template: ` <h1>Inline HTML template</h1> <hr> <h2> Встроенный HTML шаблон из трёх строк</h2> `, styles: ['h2 {color:red;}'] })

    При использовании встроенного многострочного шаблона ограничитель строки - кавычка (') нужно заменить на другой символ - ` (backtick symbol слева сверху на клавиатуре)

    Angular 5 web-start.top

    Интерполяция строк (использование динамических данных)

    (Angular string interpolation)

    Свойства , заданные в описании класса компонента, могут быть вставлены в шаблон с использованием синтаксиса:


    {{ИМЯ_СВОЙСТВА}}


    Например, если в компоненте описано свойство title :

    export class FirstComponent{ title = 'Первый тест'; }

    То в шаблоне может быть использовано {{title}}:

    template : '<H1>{{title}}</H1>',

    Можно вставлять в шаблон свойства объекта (пример со встроенными - inline - стилями и шаблоном)

    import { Component} from '@angular/core'; @Component({ selector: 'app-my-first-component', template: ` <h1> Студент </h1> <h2> Имя: {{student.name}}</h2> <h2> Возраст: {{student.age}}</h2> <h2> Курс: {{student.course}}</h2>`, styles: ['h2 {color:red;}'] }) export class MyFirstComponent { // Описание класса student = { name: "Иванов", age: 22, course: "Angular" } }



     Подробнее - Angular components


    Структурные директивы (Angular Structural Directives)

    Структурные директивы отвечают за компоновку HTML - макета. Они формируют или изменяют структуру DOM, как правило, путем добавления, удаления или изменения элементов. 

    Директива ngFor

    Можно в объекте описать массив данных, тогда в шаблон можно вставлять элементы массива или, например, с помощью оператора ngFor пробегать по всему массиву в цикле.

    import { Component} from '@angular/core'; @Component({ selector: 'app-my-first-component', template: ` <h1> Студент </h1> <h2> Имя: {{students[0].name}}</h2> <h2> Возраст: {{students[0].age}}</h2> <h2> Курс: {{students[0].course}}</h2> `, styles: ['h2 {color:red;}'] }) export class MyFirstComponent { students = [ { name: "Иванов", age: 21, course: "'Angular 2'" }, { name: "Петров", age: 22, course: "'Angular 4'" }, { name: "Сидоров", age: 23, course: "'Angular 5'" }, ] }


    Angular 5 web-start.top

    Проход по массиву в цикле

    import { Component} from '@angular/core'; @Component({ selector: 'app-my-first-component', template: ` <h1> Студенты </h1> <ul> <li *ngFor="let item of students; let i = index"> {{i}} <b>{{students[i].name}}</b> {{students[i].age}} {{students[i].course}} </li> </ul> `, styles: ['h2 {color:red;}'] }) export class MyFirstComponent { students = [ { name: "Иванов", age: 21, course: "'Angular 2'" }, { name: "Петров", age: 22, course: "'Angular 4'" }, { name: "Сидоров", age: 23, course: "'Angular 5'" }, ] }



    Подробнее - Angular directives


  • Angular 6 component interaction

    Обмен данными между родительским и дочерним компонентом (Angular component interaction)

    @input


    @output


    Decorators


    Event emitter


    C помощью декораторов @Input, @Output и API EventEmitter можно обеспечить обмен данными между родительскими и дочерними компонентами.


    Декоратор @Input

    Дочерний компонент с помощью декоратора input может получать данные от родительского, а  с помощью декоратора output - посылать.


    Для получения данных от родительского компонента дочерним:

    - в дочернем компоненте создаём свойство, в которое данные будем получать, декорируем его с помощью декоратора @Input

    - в родительском компоненте создаём public - свойство, которое будем передавать

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


    Родительский компонент:

    import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; public string1 = <string> 'Data from parent...'; }


    Шаблон родительского компонента - вызов дочернего:

    <h1>This is parent component:</h1> <hr> <app-inoutcomponent [inFromParent]='string1'></app-inoutcomponent>


    Дочерний компонент

    import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'app-inoutcomponent', templateUrl: './inoutcomponent.component.html', styleUrls: ['./inoutcomponent.component.css'] }) export class InoutcomponentComponent implements OnInit { @Input() public inFromParent: string; constructor() { } ngOnInit() { } }


    Шаблон дочернего компонента 

    <h1>This is child component:</h1> <h3>{{inFromParent}}</h3>


    Результат



    Добавим в родительский компонент метод, который меняет это свойство. Привяжем его к событию click кнопки.

    import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; public string1 = <string> 'Data from parent...'; changeChildData() { this.string1 += ' Changed '; } }


    При каждом нажатии к строке будем приписывать текст: this.string1 += ' Changed ';


    Результат после 2-х кликов:



    Декоратор @Output и  EventEmitter 

    Передача данных от дочернего компонента к родительскому.

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


    У дочернего компонета создаём своё событие - outToParent (объект класса EventEmitter ), декорируя его декоратором @Output.

    Создадим в дочернем компоненте метод - sendToParent() . Его задача: передать событие родительскому объекту (метод emit()).

    Передано это событие будет через Angular объект - $event.

    Таким образом, созданное нами событие - outToParent произойдёт в тот момент, когда сработает sendToParent()и его (события) содержимое можно будет получить из $event.


    Дочерний компонент

    import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-inoutcomponent', templateUrl: './inoutcomponent.component.html', styleUrls: ['./inoutcomponent.component.css'] }) export class InoutcomponentComponent implements OnInit { @Input() public inFromParent: string; @Output() public outToParent = new EventEmitter(); constructor() { } ngOnInit() { } sendToParent() { this.outToParent.emit('Child sent this message to parent...'); } }


    Привяжем обработчик событий - click к кнопке в шаблоне дочернего компонента и по этому клику вызовем метод sentToParent, который в свою очередь включит событие outToParent:

    Шаблон дочернего компонента

    <h1>This is child component:</h1> <h3>{{inFromParent}}</h3> <br> <button (click)='sendToParent()'>Click to send data!</button> <br>


    Стиль дочернего компонента

    * {
    color: green;
    }



    Родительский компонент получает данные события методом, который мы в нём создали - getNessage()

    import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; public string1 = <string> 'Data from parent...'; public string2 = ''; changeChildData() { this.string1 += ' Changed '; } receiveFromChild(evnt){ this.string2 = evnt; } }



    Шаблон родительского компонента (outToParent - новое событие, которое мы создали)

    <h1>This is parent component:</h1> <button (click)='changeChildData()'>Change child data </button> <hr> <strong>{{string2}}</strong> <app-inoutcomponent (outToParent)='receiveFromChild($event)' [inFromParent]='string1'></app-inoutcomponent>


    До клика



    После клика



    Декоратор @Component, свойства - inputs, outputs


    Вместо использования декораторов свойств - @Input и @Outpur можно использовать свойства декоратора класса - @Component (inputs, outputs).


    import { Component, OnInit, EventEmitter } from '@angular/core'; // import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-inoutcomponent', templateUrl: './inoutcomponent.component.html', styleUrls: ['./inoutcomponent.component.css'], inputs: ['inFromParent'], outputs:['outToParent'] }) export class InoutcomponentComponent implements OnInit { // @Input() public inFromParent: string; inFromParent: string; // @Output() public outToParent = new EventEmitter(); outToParent = new EventEmitter(); constructor() { } ngOnInit() { } sendToParent() { this.outToParent.emit('Child sent this message to parent...'); } }


    Но Angular рекомендуют использовать @Input и @Output 

    https://angular.io/guide/styleguide#style-05-12)%20(use-output-property-decorator

    style 05-12






  • Angular 6 components

    Angular 5 компоненты (Angular components)

    Компонент - базовый элемент структуры Angular - приложения

    • создать компонент
    • зарегистрировать в модуле
    • добавить HTML elelement в шаблон

    Самый простой компонент - один файл:

    import { Component} from '@angular/core'; @Component({ selector: 'comp1', template: '<h1>Comp1Component</h1>' }) export class Comp1Component { }

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

    app.module.ts

    import { Comp1Component } from './comp1/comp1.component';

    и

    @NgModule({ declarations: [ AppComponent, Comp1Component ],


    Дальше в шаблоне можно использовать тег <comp1>

    Создать компонент Angular 5

    Внутри папки app создать папку для компонента

    component2

    В этой папке создать TypeScript файл с описанием класса компонента

    component2.component.ts

    import {Component} from "@angular/core"; @Component ({ selector : 'app-test2', templateUrl: './test2.component.html', styleUrls: ['./test2.component.css'], }) export class Test2Component{ }


    Строка 

    import { Component} from '@angular/core';

    импортирует декоратор компонента из библиотеки Angular core

    Создать файлы шаблона и стиля компонента (test2.component.html и test2.component.css)

    В файле описания модуля (app.module.ts) мпортировать новый компонент, используя имя файла с его описанием без расширения ts 

      (import { Test2Component } from './test2/test2.component';) 

    и зарегистрировать новый компонент в в секции declarations декоратора модуля - @NgModule 


    @NgModule({ declarations: [ AppComponent, Test2Component ], imports: [ BrowserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }


    Добавить вызов нашего компонента в шаблон главного компонента приложения (app.component.html)

    <app-test2> </app-test2>

    Компоненты могут быть вложенными.

    Компонент можно использовать несколько раз.

    Например:

    <app-test2> </> <app-test1> </app-test1> <app-test1> </app-test1> </app-test2>

    Селектор компонента

    В декораторе компонента одно из свойств - селектор компонента.

    По этому свойству Angular определяет, в какое место шаблона компонент должен быть помещён.

    В качестве селектора обычно используется имя тега,  который будет идентифицировать компонент в шаблоне.

    selector : 'app-test2-component',

    Место компонента в шаблоне в этом случае должно быть задано тегом:

    <app-test2> </app-test2>

    Но можно также использовать название атрибута тега

    selector : '[app-test2]',

    или название класса

    selector : '.app-test2]',

    Место компонента в шаблоне в этом случае может быть задано как :

    <div app-test2> </div>

    или

    <span class="app-test2"> </span>


  • Angular 6 data binding

    Angular 5 databinding

    Связывание данных (обмен данными между приложением и окном браузера) - это механизм связи между тем, что видят пользователи в окне браузера, и теми данными, которыми манипулирует приложение (компонент). 

    Достаточно описать связь между данными компонента (различными свойствами компонента) с одной стороны и данными, которые отображает в окне браузера HTML шаблон компонента, с другой.

    Angular будет автоматически отслеживать эти изменения, отображая в окне браузера и меняя данные приложения.

    Можно разделить способы обмена данными между приложением и его шаблоном на несколько категорий:

    • передача данных от шаблона в компонент (Angular string interpolation, property binding, class binding, style bynding, ngStyle, ngClass)
    • отслеживание событий, связвнных с DOM элементами шаблона (Angular Event Binding, $event)
    • двусторонний обмен данными между шаблоном и компонентом (Angular two-way data binding, ngModel)


    Интерполяция (Angular string interpolation)

    {{expression}}
    [target]="expression"
    bind-target="expression"

    Обработка событий в окне


    (target)="statement" on-target="statement"

    Можно использовать встроенный Angular объект - $event. Он автоматически привязывается к использующему его событию. Его свойства содержат свойства события и сыойства элемента, который это событие обработал

    Пример:

    import { Component} from '@angular/core'; @Component({ selector : 'app-comp2', template : ` <h1> $event properties - > to console </h1> <button class='btn' (click)='displEvntProp($event)'>Log $event properties</button> `, styles : [''] }) export class Comp2Component { constructor() { } displEvntProp(evnt){ console.log(evnt); } }


    event filter 

    Template variable

    #var1 = template reference variables in Angular

    Эта переменная будет содержать ссылку на DOM элемент

    <input type="text" (change)="true" #variable> {{ variable.value }} <my-component #variable [input]="'hello'"></my-component> {{ variable.input }} <form #variable="ngForm"> <!-- some more HTML... --> <button type="submit" [disabled]="variable.form.invalid">Submit!</button> </form>

    console.log($event) - вывести в консоль все его свойства, методы

    Event bubbling - отслежтванте события всеми родительскими элементами в пррядке иерархии

    $event.stopPropagation() - метод, который отменяет процесс event bubbling

    Пример:



    (String interpolation, property binding, custom variables)

    <div style="text-align:center"> <h1> Пример : {{ title }}! </h1> </div> <hr> <button id="myButton" #myBut1 type="submit" class="btn btn-default" [disabled]="buttonDisabled" [style.color]="buttonColor" (click)="myButClick($event)"> <i>{{buttonText}}</i> </button> <p style="color:blue" [innerHTML]="myBut1.innerText"></p> <p style="color:red">{{buttonText}} </p> <hr>



    import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'data binding test'; buttonDisabled = true; buttonText = "Ждите"; buttonColor = "red"; evntOut; constructor (){ setTimeout(()=>{ this.buttonDisabled = false; this.buttonText = "Вводите"; this.buttonColor = "green"; },5000); } myButClick (evnt){ this.buttonText = "Нажали уже!" ; this.buttonDisabled = true; this.evntOut = evnt; console.log(evnt); }; }




    Переменные шаблона

    Templaеу variable #var1 = template reference variables in Angular

    Эта переменная будет содержать ссылку на DOM элемент

    <input type="text" (change)="true" #variable> {{ variable.value }} <my-component #variable [input]="'hello'"></my-component> {{ variable.input }} <form #variable="ngForm"> <!-- some more HTML... --> <button type="submit" [disabled]="variable.form.invalid">Submit!</button> </form>

    Двусторонний обмен данными

    Директива ngModel  

    Содержится в модуле 


    [(target)]="expression"
    bindon-target="expression" <example-component [(message)]="title"></example-component> Name: <input type="text" [(ngModel)]="name" /> <div>{{name}}</div>


    Импортировать в app.module.ts

    import { FormsModule } from '@angular/forms'; // Importing forms module to this file

    и  

    imports: [ BrowserModule, FormsModule // Importing forms module to application module ],

    Angular обеспечивает простой способ обработки событий, связанныз с элементами DOM. 

    Метод двусторонней привязки помогает поддерживать синхронизацию данных и управление вводом.


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

    <input [(ngModel)]="name" >

    Это эквивалентно:

    <input [ngModel]="name" (ngModelChange)="name=$event">



    Pipes

    Последовательное поточное динамическое форматирование данных


    BuiltIn pipes

    DatePipe, UpperCasePipe, LowerCasePipe, CurrencyPipe, PercentPipe.



    Custom pipes



  • Angular 6 directives (part1)

    Директивы (Angular directives)

    Директивы используятся для манипуляций с DOM: удалить, добавить, изменить  элемент или его свойства-атрибуты.

    Angular 5 использует директивы, которые можно разделить на:

    • Компоненты (Angular  components)
    • Структурные директивы (Angular structural directives)
    • Директивы-атрибуты (Angular attribute directives)
    • Встроенные директивы (Angular built in directives)
    • Пользовательские директивы (Angular custom directives)


    Компоненты (Angular components)

    Тип директивы, который использует шаблон. Это наиболее часто используемый тип директив. Angular. Внутри такой директивы можно использовать другие директивы, типа: всроенные, пользовательские.

    Создать компонент

    ng generate component students

    Angular CLI создаст в папке ./src/app файлы компонента:

    • students.component.css
    • students.component.html
    • students.component.spec.ts
    • students.component.ts

    TypeScript код компонента - в файле: students.component.ts

    import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-students', templateUrl: './students.component.html', styleUrls: ['./students.component.css'] }) export class StudentsComponent implements OnInit { constructor() { } ngOnInit() { } }


    В файл app-modules.ts автоматически добавляются строки:

    import { StudentsComponent } from './students/students.component';

    и в секцию declaration:

    declarations: [ ..., StudentsComponent ]


    Структурные (Angular structural directives)

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

    Структурные директивы могут использоваться с HTML тегом <ng-template> или без него.

    Существуют три встроенных структурных директивы: NgIf, NgFor и NgSwitch.

    Структурные директивы - это тип директив, которыя изменяют структуру DOM. Тег <ng-template> можно использовать, чтобы определить элемент, который мы хотим вставить в DOM. Можно добавить имя директивы с помощью *,  чтобы пропустить определение <ng-template> и использовать в качестве шаблона директивы элемент, к которому она привязана .

    Изменим шаблон компонента:

    <h2> Компонент {{name}} работает </h2> <ng-template [ngIf]=" students.length > 0"> <h3>Список студентов:</h3> </ng-template> <ul> <ng-template ngFor let-student [ngForOf]="students" ; let-i="index"> <li>Номер: {{i+1}} Имя:{{student[0]}} Курс:{{student[2]}}</li> </ng-template> </ul> <hr> <ul *ngFor="let student of students; even as i" [ngSwitch]="i"> <li style="background-color:gray" *ngSwitchCase="true">Четный:{{i}} Курс:{{student[2]}}</li> <li style="background-color:lightGray" *ngSwitchCase="false">Четный:{{i}} Курс:{{student[2]}}</li> <i *ngSwitchDefault>{{i}} Курс:{{student[2]}}</i> </ul> <hr>


    Тег <ng-template>

    <ng-template [ngIf]='condition'> <p>I am the content to show</p> </ng-template>


    ngIf

    <div *ngIf="condition">...</div>
    <ng-template [ngIf]="condition"><div>...</div></ng-template>
    <div *ngIf="condition; then thenBlock else elseBlock"></div> <ng-template #thenBlock>...</ng-template> <ng-template #elseBlock>...</ng-template>
    <div *ngIf="condition as value; else elseBlock">{{value}}</div> <ng-template #elseBlock>...</ng-template>


    ngFor (ngForOf)

    Синтаксис:

    <li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>


    <ng-template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn"> <li>...</li> </ng-template>


    <ng-container *ngFor = " let item of items; let i = index"> <li [innerHTML] = 'item'>...</li> </ng-container>


    Локальные переменные ngFor

    • index: number: индекс текущего элемента в итерации
    • first: boolean: ИСТИНА , если элемент - первый в итерации
    • last: boolean: ИСТИНА , если элемент - последний в итерации
    • even: boolean: ИСТИНА , если элемент имеет чётный индекс
    • odd: boolean: ИСТИНА , если элемент имеет нечётный индекс


    Пример:


    <ul>Список студентов: <ng-template ngFor let-student [ngForOf]="students" ; let-i="index"> <li>Номер: {{i+1}} Имя:{{student[0]}} Курс:{{student[2]}}</li> </ng-template> </ul>


     


    NgSwitch

    Используем в качестве переключателя внутреннюю переменную even цикла ngFor 

    <container-tag *ngFor="let student of students; even as i" [ngSwitch]="i"> <case1-tag style="background-color:gray" *ngSwitchCase="true">Четный:{{i}} Курс:{{student[2]}}</case1-tag> <case2-tag style="background-color:lightGray" *ngSwitchCase="false">Четный:{{i}} Курс:{{student[2]}}</case2-tag> <caseDefault-tag*ngSwitchDefault>{{i}} Курс:{{student[2]}}</caseDefault-tag> </container-tag>


    <ul *ngFor="let student of students; even as i" [ngSwitch]="i"> <li style="background-color:gray" *ngSwitchCase="true">Четный:{{i}} Курс:{{student[2]}}</li> <li style="background-color:lightGray" *ngSwitchCase="false">Четный:{{i}} Курс:{{student[2]}}</li> <i *ngSwitchDefault>{{i}} Курс:{{student[2]}}</i> </ul>



    Тег <ng-container>

    <ng-container *ngIf="lessons"> <div class="lesson" *ngFor="let lesson of lessons"> <div class="lesson-detail"> {{lesson | json}} </div> </div> </ng-container>




    Директивы-свойства (Angular 5 attribute directives)

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


    Встроенные директивы (Angular built in directives)

    Это, например, директивы:

    • NgIf
    • NgSwitch
    • NgStyle
    • NgClass

    Пользовательские директивы (Angular custom derectives)

    Создать директиву

    ng create directive my-dir1

    Простой пример1

    Отредактировать TypeScript - my-dir1.directive.ts

    import { Directive, ElementRef, Renderer2 } from '@angular/core'; @Directive({ selector: '[appMyDir1]' }) export class MyDir1Directive { constructor(myElement: ElementRef, myRenderer: Renderer2) { myRenderer.setStyle(myElement.nativeElement, 'box-shadow', '2px 2px 12px #ccc'); myRenderer.setStyle(myElement.nativeElement, 'padding', '10px 20px'); } }


    Шаблон

    <div style="text-align:center"> <h1> Welcome to {{ title }}! </h1> <hr> <span></span> <span appMyDir1>Test directive</span> </div>



    Класс ElementRef  обеспечивает доступ к объектам DOM

    Класс Renderer2 

    Класс Renderer2 представляет собой абстракцию, предоставляемую Angular в виде сервиса, который позволяет управлять элементами приложения без непосредственного доступа к DOM. Это рекомендуемый подход, потому что он упрощает разработку приложений, которые могут отображаться в средах, не имеющих доступа к DOM, например, на сервере, web-workers или на мобильном устройстве.

    Renderer2 часто используется в пользовательских директивах из-за того, что Angular директивы используются для модификации элементов. 

    Этот пример В этом примере мы создаем новый div и создаем текстовый узел. Затем мы помещаем текстовый узел в наш новый div и, наконец, наш div добавляется к элементу, на который ссылается наша директива:

    constructor(private renderer: Renderer2, private el: ElementRef) {} ngOnInit() { const div = this.renderer.createElement('div'); const text = this.renderer.createText('Hello world!'); this.renderer.appendChild(div, text); this.renderer.appendChild(this.el.nativeElement, div); }



  • Angular 6 forms

    Использование форм в Angular 

    Angular имеет свой собственный набор библиотек для построения сложных форм. Последняя версия Angular имеет две мощные стратегии построения форм:

    • шаблонные формы (Angular template-driven forms - FormsModule
    • модельные или реактивные формы (Angular reactive forms - ReactiveFormsModule

    Обе технологии работы с формами принадлежат библиотеке @ angular/forms и основаны на одних и тех же классах управления формой. Тем не менее, они значительно отличаются в своей философии, стиле программирования и технике. 

    С формой, управляемой шаблоном, большая часть работы выполняется в шаблоне; и с формой, управляемой моделью, большая часть работы выполняется в классе компонентов.




    Шаблонные формы (Angular template-driven forms)

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

    Когда мы создаём в шаблоне элемент FORM, Angular привязывает к этому элементу директиву ngForm (например: <form #myForm = 'ngForm'>). Создаём объект myForm из ngForm (ngForm instance)

    Эта директива даёт:

    значения полей формы

    статус полей (Valid/Invalid)

    Angular отслеживает событие submit (например: нажатие кнопки <input type=submit> или <button type=submit> и ьд) для формы через обработчик событий - ngSubmit. При возникновении события submit Angular инициирует слбытие ngSubmit, к которому мы привязываем обработчик событий .

    <form #myForm = 'ngForm' (ngSubmit) = 'mySubmit(myForm.value)'>

    Для каждого элемента input формы необхлжтил задаьб атрибут name и дтрективу ngModel.

    <input id="inputName" type="text" placeholder='nae' name='name' ngModel>

    При этом в переменную myForm.value будут занесены данные формы.

    Пример1

    Далее в примере используем Angular директивы для форм:

    ngForm - создаём объект - форма (в переменной myForm)

    ngModel - включаем поле ввода в объект с данными формы

    ngModelGroup - создаём в объекте, содержащем данные формы, дочерний объект - группу даных

    ngValue - при необходимости задаём значения для полей ввода

    Angular - событием ngSubmit вызываем метод mySubmit(), передавая ему в качестве параметра объект со значениями формы (myForm.value). Все свойства этого объекта - https://angular.io/api/forms/NgForm.


    Импортируем FormsModule (в app.modules.ts)

    import {FormsModule} from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { FormComponent } from './form/form.component'; @NgModule({ declarations: [ AppComponent, FormComponent ], imports: [ BrowserModule, FormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }



    Компонент

    import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-form', templateUrl: './form.component.html', styleUrls: ['./form.component.css'] }) export class FormComponent implements OnInit { constructor() { } ngOnInit() { } mySubmit(val){ console.log(val); } }



    Шаблон - HTML

    <form #myForm='ngForm' (ngSubmit)='mySubmit(myForm.value)'> <label for="inputName">Name</label> <input id="inputName" type="text" placeholder='Your name' name='name' ngModel> <label for="inputEmail">Email</label> <input id="inputEmail" type="e-mail" placeholder='e-mail' name='mail' ngModel> <div ngModelGroup='pwd'> <label for="inputPassword">Password</label> <input type="password" id="inputPassword" placeholder="Password" name='passwd' ngModel> <label for="confirmPassword">Confirm Password</label> <input type="password" id="confirmPassword" placeholder="Confirm password" name='passwdConf' ngModel> </div> <label for="select">Gender</label> <select id="select" name='gender' ngModel="0"> <option ngValue='0'>Genger</option> <option ngValue='m'>Male</option> <option ngValue='f'>Female</option> <option ngValue='o'>Other</option> </select> <label for='agreement'>Confirm that you've read the Terms and Conditions </label> <input id='agreement' type="checkbox" name='agreement' ngModel> <hr> <button type="reset" class="btn btn-default">Cancel</button> <button type="submit" class="btn btn-primary">Submit</button> </form>



    Стили


    ::placeholder { color: rgba(255, 0, 0, 0.513); font-style: italic; } INPUT, SELECT { display: block; margin: 5px; padding: 3px 5px; } BUTTON { margin: 10px; padding: 5px 15px; } LABEL { font-weight: bold; }



    Результат (объект с данными формы и в нём - дочерний объект - пароли)





    Проверка данных формы (Angular form validation)

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

    Классы стилей, которые Angular меняет:

    Статус элемента (INPUT, SELECT,...)Класс, в случае: истина (true)Класс, в случае: ложь (false)
    Элемент управления был посещён (visited )ng-touchedng-untouched
    Значения элемента изменено (value has changed)ng-dirtyng-pristine
    Значение элемента формы верно (value is valid)ng-validng-invalid

    Свойства (статус) элемента управления (https://angular.io/api/forms/NgControlStatus), которыми можно пользоваться:

    • untouched 
    • touched 
    • pristine 
    • dirty 
    • invalid 
    • valid 
    • submitted (для объекта - формы)


    При проверки данных формы можно использовать атрибуты элемента (например: min, max, required, email, minlength, maxlength,... ) и проверку на соответствие шаблону (атрибут pattern), который задаётся в формате Regular Expressions.

    (https://angular.io/api/forms/Validators)



    В примере мы будем использовать:


    Компонент.

    Метод mySubmit() выводит на консоль данные формы.

    import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-form', templateUrl: './form.component.html', styleUrls: ['./form.component.css'] }) export class FormComponent implements OnInit { constructor() { } ngOnInit() { } mySubmit(formObj){ console.log(formObj.value); console.log(formObj.controls); } }



    HTML - шаблон компонента (form.component.html).

    В переменной шаблона #myForm создаём из нашей формы объект типа ngForm (#myForm='ngForm')

    К событию ngSubmit привязываем обработчик - метод mySybmit() и передаём ему вкачестве параметра нашу форму (объект myForm ). Единственая функция этого метода в нашем примере - распечатать в консоль данные формы.

    К полям ввода добавляем параметры name и директиву ngModel, чтобы использовать этот элемент в нашем объекте myForm.

    Вводим в некоторые поля INPUT переменные шаблона, которым присваиваем ngModel - получаем возможность через эту переменную использовать все возможные свойства ngModel (параметры, статус,...).

    Создаём для некоторых полей ввода DIV, в который будем выводить сообщение об ошибке (присвоим ему class='myError').

    Этот элемент должен появляться только тогда, когда есть ошибка. Для этого присваиваем его свойству hidden свойство valid поля ввода (свойство valid того элемента input , к которому мы обращаемся по имени переменной, которую ему присвоили). Angular по результатам проверки данных в этом поле выставляет его свойство valid в false или true. 

    В теге input с именем name задано свойство: required. Это - один из встроенных валидаторов Angular (https://angular.io/api/forms/Validators).

    Если в поле нет значения, то валидатор включает статус элемента ввода: invalid (и элементу автоматически присваивается CSS класс: ng-invalid, что тоже можно использовать ) .

    Для контоля данных, вводимых в поле ввода mail используем один из встроенных валидаторов Angular - email (https://angular.io/api/forms/Validators).

    В поле ввода пароля используем 2 валидатора: minlength='7' и pattern='\w*'. Первый - ограничивает мин длину пароля, второй разрешает использовать в пароле только буквы, цифры и символ подчеркивания (Regular Expressins \w*).

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

    Для этого создаём для каждой ошибки свой элемент DIV.

    Атрибут hidden этого элемента привязываем к истинности значений, которые получаем из метода hasError() нашего элемента ввода (https://angular.io/api/forms/NgModel), передавая ему в качестве параметра имя валидатора, который включил ошибку.

    Значение  pwdInput.hasError("minlength") примет значение true в том случае, если ошибку включи валидатор minlength.

    После поля подтверждения пароля (pwConf) тоже ставим элемент DIV для вывода ошибки повтора пароля. Для его появления или отсутствия в окне браузера используем другой способ (можно было бы также управлять его свойство hidden) - директиву *ngIf.

    В качестве условия вставляем логическое выражение - результат сравнения паролей в двух полях:

     pwdInput.value == pwdConf.value

    Для того, чтобы исключить появление в окне этого элемента до того момента, как вообще начали  вводить пароль, используем свойство поля ввода пароля - pwdInput.dirty (менялось ли поле с момента загруззки страницы). И условие появления в окне нашего элемента принимает вид:

    *ngIf='!(pwdInput.value == pwdConf.value) && pwdInput.dirty'

    В поле ввода select - option (gender ) используем одно из полей option в качестве подсказки пользователю.

    Создаём поле <option ngValue='0'>Genger</option> и с помощью директивы ngModel="0" делаем его selected в момент загрузки странички (атрибут поля option - selected не работает).

    Кнопку submit формы

    <button [disabled]='!myForm.valid' type="submit">Submit</button>

    делаем недоступной до того момента, пока данные формы не введены корректно (myForm.valid = true)

    Информационно поле:

    <div *ngIf='myForm.submitted' class='submitedMsg'>Your form successfully submitted</div>

    Появляется в том случае, если истинно условие: myForm.submitted.


    <form #myForm='ngForm' (ngSubmit)='mySubmit(myForm)'> <div> <label for="inputName">Name</label> <input type='text' #nameInput='ngModel' id="inputName" required type='text' placeholder='Your name' name='name' ngModel> <div [hidden]='nameInput.valid ' class='myError'>Name required!</div> </div> <div> <label for="inputEmail">Email</label> <input id="inputEmail" #mailInput='ngModel' type='text' email placeholder='e-mail' name='mail' ngModel> <div [hidden]='mailInput.valid ' class='myError'>Incorrect mail format!</div> </div> <div ngModelGroup='pwd'> <label for="inputPassword">Password (digits only)</label> <input #pwdInput='ngModel' type="password" id="inputPassword" placeholder="Password" name='passwd' minlength='7' pattern='\w*' ngModel> <div [hidden]='!pwdInput.hasError("minlength")' class='myError'>Password minimum length: 7 symbols!</div> <div [hidden]='!pwdInput.hasError("pattern") ' class='myError'>Password could contain letters, numbers or underscores only!</div> <label for="confirmPassword">Confirm Password</label> <input #pwdConf='ngModel' type="password" id="confirmPassword" placeholder="Confirm password" name='passwdConf' ngModel> <div *ngIf='!(pwdInput.value == pwdConf.value) && pwdInput.dirty' class='myError'>Passwords do not match</div> </div> <div> <label for="select">Gender</label> <select id="select" name='gender' ngModel="0"> <option ngValue='0'>Genger</option> <option ngValue='m'>Male</option> <option ngValue='f'>Female</option> <option ngValue='o'>Other</option> </select> </div> <div> <label for='agreement'>Confirm Terms and Conditions </label> <input id='agreement' type="checkbox" name='agreement' ngModel> </div> <div> <button type="reset" class="btn btn-default">Cancel</button> <button [disabled]='!myForm.valid' type="submit">Submit</button> </div> </form> <hr> <div *ngIf='myForm.submitted' class='submitedMsg'>Your form successfully submitted</div>



    Стили компонента (form.component.css)

    Определяем, в частности, свойства стилей для классов: .ng-valid (зелёная граница слева) и .ng-invalid (красная граница слева)

    FORM { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 10px; } FORM>DIV { box-shadow: 0px 0px 2px 2px rgba(100, 100, 100, 0.3); padding: 5px; } ::placeholder { color: rgba(0, 68, 255, 0.513); font-style: italic; } INPUT, SELECT { display: block; margin: 5px; padding: 10px; width: 95%; } INPUT[type='checkbox'] { width: auto; float: right; } FORM>DIV:last-child { text-align: center; } BUTTON { margin: 10px; padding: 5px 15px; } LABEL { font-weight: bold; } /* Form validation classes */ INPUT.ng-valid { border-left: 5px solid green; } INPUT.ng-invalid { border-left: 5px solid red; } .myError { border-left: 1px solid red; padding: 5px; color: red; } .myError:before { content: 'Error message: '; } .submitedMsg { border-left: 5px solid blue; padding: 20px 10px; color: red; box-shadow: 0px 0px 10px 5px rgba(0, 0, 0, 0.2); }



    app.module.ts

    import {FormsModule} from '@angular/forms'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { FormComponent } from './form/form.component'; @NgModule({ declarations: [ AppComponent, FormComponent ], imports: [ BrowserModule, FormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }



    Результат - после загрузки страницы (кнопка submit недоступна, под полем ввода имени - сообщение об ошибке):


    Результат - ввели имя


    Вводим неправильный e-mail (кнопка submit опять недоступна и под полем mail - сообщение об ошибке)


    Ввели правильный e-mail, вводим пароль - 123+.

    Появляются сразу 2 сообщения об ошибке в пароле: количество символов недостаточно и символ + недопустим и сообщение о неправильно подтверждённом пароле.


    Вводим всё, как положено, и нажимаем SUBMIT




    Модельные формы (Angular "model-driven" или "reactive" forms )

    В отличие от форм, управляемых шаблоном, модельные (Angular Model-driven or Reactive forms) формы управляются моделью, которая описывается в компоненте формы.

    Пример1


    Создаём компонент form2 и описываем в нём модель нашей формы. Модель сохдаём в переменной myForm2 , пользуясь классом FormGroup и классом FormControl, которые импортируем их @angular/forms.

    Модель простая - 2 поля ввода.

    Создаём метод mySubmit, который данные формы выводит в консоль.


    import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl} from '@angular/forms'; @Component({ selector: 'app-form2', templateUrl: './form2.component.html', styleUrls: ['./form2.component.css'] }) export class Form2Component implements OnInit { myForm2 = new FormGroup({ name: new FormControl(), mail: new FormControl() }); constructor() { } ngOnInit() { } mySubmit(){ console.log(this.myForm2.value); } }


    В app.module для использования Reactive - форм импортируем ReactiveFormsModule


    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { ReactiveFormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { Form2Component } from './form2/form2.component'; @NgModule({ declarations: [ AppComponent, Form2Component ], imports: [ BrowserModule, ReactiveFormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }



    Создаём шаблон компонента, в котором привязываем форму к модели ([formGroup]='myForm2'), описываем для ней событие ngSubmit , привязываем каждое поле ввода к соответствующей ему переменной в модели (formControlName='ИМЯ_СВОЙСТВА_В_МОДЕЛИ')


    <form [formGroup]='myForm2' (ngSubmit)="mySubmit()"> <input formControlName='name'> <input formControlName='mail'> <button type='submit'>Submit form </button> </form>


    Результат:







    Пример2


    Создаём модель, в которой используем также и проверку данных формы.

    Для этого нужны : FormControl , FormGroup, Validators 

    Создаём компонент, импортируем в него: FormGroup? ForControl , Validators 


    import { Component, OnInit } from '@angular/core'; import { FormGroup, FormControl, Validators } from '@angular/forms'; @Component({ selector: 'app-react-form', templateUrl: './react-form.component.html', styleUrls: ['./react-form.component.css'] }) export class ReactFormComponent implements OnInit { submitDisabled: boolean; submitButtonText: string; myForm = new FormGroup({ name: new FormControl(null, Validators.required), email: new FormControl('', Validators.email), address: new FormGroup({ street: new FormControl(), city: new FormControl(), postalcode: new FormControl() }), }); constructor() { this.submitDisabled = true; this.submitButtonText = 'Submit disabled'; } ngOnInit() { } myFormSubmit() { if (this.myForm.valid) { this.submitDisabled = false; this.submitButtonText = 'Click to submit data'; } else { this.submitDisabled = true; this.submitButtonText = 'Submit disabled'; } console.log(this.myForm.value); } myFormInput(){ if (this.myForm.valid) { this.submitDisabled = false; this.submitButtonText = 'Click to submit data'; } else { this.submitDisabled = true; this.submitButtonText = 'Submit disabled'; } console.log(this.myForm.value); } }



    myForm - модель нашей формы. Теперь она содержит поля (элементы управления - FormControls) : name, email, street, city, postalcode 



    myForm = new FormGroup({ name: new FormControl(null, Validators.required), email: new FormControl('', Validators.email), address: new FormGroup({ street: new FormControl(), city: new FormControl(), postalcode: new FormControl() }), });




    Причём:

    • поля street, city, postalcode сгруппированы в отдельный объект - address FormGroup
    • поля naeme, email передают 2 параметра в FormControl : начальное значение и тот валидатор, который будет использоваться при проверки данных в поле ввода.


    Компонент использует 2 переменные :  submitDisabled: boolean и submitButtonText: string.

    В первой храним статус кнопки SUBMIT, во второй - текст кнопки.

    Значения переменных меняем динамически и используем их в шаблоне компонента.


    Компонент использует 2 метода: 

    • myFormSubmit() - привязан в шаблоне к событию формы (ngSubmit)
    • myFormInput() - привязан к событию формы - (change)

    HTML шаблон компонента (првязываем форму к модели : [formGroup]="myForm" ) и каждый элемент - к переменной моделию. Группу элементов address объединяем в элементе div id='address':



    <form id='myForm' [formGroup]="myForm" (ngSubmit)='myFormSubmit()' (input)='myFormInput()'> <div class='controlGroup'> <label>Name</label> <input type='text' formControlName='name' placeholder="name"> </div> <div class='controlGroup'> <label>E-mail</label> <input type='text' formControlName='email' placeholder="E-Mail"> </div> <div id='address' formGroupName='address'> <div class='controlGroup'> <label>Street</label> <input type='text' formControlName='street' placeholder="street"> </div> <div class='controlGroup'> <label>City</label> <input type='text' formControlName='city' placeholder="city"> </div> <div class='controlGroup'> <label>Postalcode</label> <input type='text' formControlName='postalcode' placeholder="postalcode"> </div> </div> <div class='controlGroup submit'> <div id='myError' *ngIf='myForm.invalid'>Incorrect form data found! Submit disabled. Check input fields</div> <div id='myCorrect' *ngIf='myForm.valid'>All form data typed correctly Press submit button to send it... </div> <button class='myButton' type='submit' [disabled]='submitDisabled' [innerText]='submitButtonText'></button> </div> </form>



    Файл со стилями:


    * { --myColor1: #0a100d; --myColor2: #abac97; --myColor3: #f1f0e2; --myColor4: #a22c29; --myColor5: #902923; } BODY { background-color: #FFF; }

    /* Grid layout styles begin */ #myForm { display: grid; grid-template-columns: 1fr; grid-gap: 10px; } #address { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-column-gap: 10px; } .controlGroup { display: grid; grid-template-rows: 1fr 1fr; } DIV.submit { justify-content: center; align-content: center; } /* Grid layout styles end */ INPUT { padding: 10px; border-radius: 5px; border: 1px solid var(--myColor2); background-color: var(--myColor3); transition: border-color 1s; } INPUT:hover { border-color: var(--myColor1); } INPUT:focus { outline: none; background-color: #FFF; } INPUT:active { box-shadow: 0 2px 5px 0px var(--myColor2) ! important; } LABEL { color: var(--myColor1); } #address { padding: 10px; border-radius: 5px; border: 1px solid var(--myColor2); } .myButton { display: inline-block; padding: 10px 50px; border: 1px solid var(--myColor2); border-radius: 10px; background-color: #FFF; color: var(--myColor2); font-size: 1.2rem; box-shadow: 0px 0px 1px 0px rgba(0, 0, 0, 0.2); transition: background-color 1s; } .myButton:hover { box-shadow: 0px 10px 20px 0px rgba(0, 0, 0, 0.2); border-color: var(--myColor5); color: var(--myColor5); transition: box-shadow 1s; } .myButton:active, .myButton:focus { outline: none; } .myButton:active { border-color: var(--myColor4); color: var(--myColor1); } .myButton:disabled { background-color: var(--myColor4); color: #FFF; box-shadow: none; transition: background-color 1s; } .myButton:disabled:hover { box-shadow: none; color: #FFF; } /* Form validation control begin */ INPUT.ng-invalid { color: var(--myColor4); border-left: 5px solid var(--myColor4); } INPUT.ng-valid { color: var(--myColor4); border-left: 5px solid var(--myColor2); } /* Form validation control end */ /* Info block before submit button */ #myError { color: var(--myColor4); width: 100%; text-align: center; padding: 10px; } #myCorrect { color: var(--myColor1); width: 100%; text-align: center; padding: 10px; }


    Загрузили страничку.

    Кнопка SUBMIT недоступна (её атрибут [disabled]='submitDisabled' имеет значение false)

    Текст на кнопке - из переменной submitButtonText ([innerText]='submitButtonText')

    Поле ввода имени помечено слева красной обводкой (стиль INPUT.ng-invalid {color: var(--myColor4);border-left: 5px solid var(--myColor4);}) из-за того, что отработал валидатор required для этого поля (name: new FormControl(null, Validators.required), никакого значения туда не введено, а начальное значение мы задали null, чего не допускает валидатор)

    Над кнопкой SUBMIT - сообщение об ошибке (по директиве ngIF отобразился <div id='myError' *ngIf='myForm.invalid'>Incorrect form data found! Submit disabled. Check input fields</div> ):



    Начинаем вводить имя.

    • Пропали сообщения об ошибках.
    • Над кнопкой submit появился другой текст (<div id='myCorrect' *ngIf='myForm.valid'>All form data typed correctly Press submit button to send it... </div>)
    • В консоли - результат работы метода myFormInput() при вводе каждого символа. Этот же метод поменял кнопку SUBMIT ( this.submitDisabled = false; this.submitButtonText = 'Click to submit data';).



    Начнём вводить e-mail.

    • Отрабатывает Validator ( проверяя корректность e-mail адреса)
    • Меняются стили поля ввода (левая граница - INPUT.ng-invalid{...})
    • Меняется кнопка
    • Меняется элемент DIV над кнопкой




    Закончим вод - нажмём SUBMIT

    Метод выводит в консоль полученные формой данные.





    Видео


    FormBuilder

    Angular FormBuilder облегчает создание форм. Он позволяет создавать элементы управления формы из модели.

    Нам понадобятся: FormGroup и FornBuilder (далее - для проверки данных - Validators ).

    Импортируем FormBuilder (import { FormGroup, FormBuilder } from '@angular/forms';)

    Пользуясь Angular dependancy injection создаём его объект в конструкторе компонента (constructor(private myFb: FormBuilder) { }).

    Используем этот объект для создания FormGroup.

    Простой пример

    Создаём объект типа FormGroup в переменной myForm5 ( myForm5: FormGroup;)

    Формируем форму в этом объекте, используя метод group() объекта formBuilder (this.myForm5 = this.myFb.group({name: 'MyName',email: 'e-mail',address: 'Addres string'});)

    Компонент

    import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; @Component({ selector: 'app-formbldr', templateUrl: './formbldr.component.html', styleUrls: ['./formbldr.component.css'] }) export class FormbldrComponent implements OnInit { myForm5: FormGroup; constructor(private myFb: FormBuilder) { } ngOnInit() { this.myForm5 = this.myFb.group({ name: 'MyName', email: 'e-mail', address: 'Addres string' }); } mySubmit(){ console.log(this.myForm5.value); } }





    HTML шаблон

    <form [formGroup]='myForm5' (ngSubmit)='mySubmit()'> <input formControlName='name'> <input formControlName='email'> <button type='submit'>Submit</button> </form>






    Пример2

    C помощью FormBuilder задаём дополнительные параметры полей ввода: начальное значение, один или несколько валидаторов

    Компонент

    import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validator, Validators } from '@angular/forms'; @Component({ selector: 'app-formbldr', templateUrl: './formbldr.component.html', styleUrls: ['./formbldr.component.css'] }) export class FormbldrComponent implements OnInit { myForm5: FormGroup; constructor(private myFb: FormBuilder) { this.myForm5 = this.myFb.group({ name: [null, Validators.required ], email: ['', Validators.compose([ Validators.required, Validators.pattern('^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$') ]) ], address: [''] }); } ngOnInit() { } mySubmit() { console.log(this.myForm5.value); } }



    Шаблон


    <form [formGroup]='myForm5' (ngSubmit)='mySubmit()'> <div class='cntrlGrp'> <label>Name</label> <input formControlName='name'> </div> <div class='cntrlGrp'> <label>email</label> <input formControlName='email'> </div> <div class='cntrlGrp'> <label>address</label> <input formControlName='address'> </div> <div class='cntrlGrp'> <label></label> <button type='submit' [disabled]='myForm5.invalid'>Submit</button> </div> </form>




    Стили


    FORM { display: grid; grid-auto-flow: row; grid-gap: 10px; } .cntrlGrp { display: grid; grid-auto-flow: column; } INPUT.ng-invalid { border-left: 5px solid red; }



     





  • Angular 6 HTTP запросы (part1)

    Angular HttpClient - работа с HTTP запросами



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


    Angular HttpClient - класс, который предоставляет пользователям удобный интерфейс для работы с HTTP запросами, он базируется на использовании XMLHttpRequest объекта браузера - .

    Для использования HttpClient API нужно импортировать модуль HttpClientModule (обычно - в app.module.ts):


    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }



    После этого можно использовать HttpClient в классе Angular - приложений, импортируя HttpClient и подключая его через dependancy injection. Например, создав сервис, который будет отвечать за передачу данных но HTTP:


    import { Injectable } from '@angular/core'; import { HttpClient} from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class Http1Service { constructor(private myHttp: HttpClient) { } }


    Объект, созданный из HttpClient (в примере выше - myHttp), поддерживает методы:


    • get
    • post
    • put
    • delete
    • patch
    • head
    • jsonp


    Для тестирования приложения Angular, которое работает с HttpClient можно использовать, например:

    • Angular модуль:  HttpClientTestingModule, 
    • специальные online сервисы, типа: http://jsonplaceholder.typicode.com/ , https://www.jsontest.com/, 
    • nodeJs (Angular in-memory web API: npm i angular-in-memory-web-api@0.5.3 --save ).
    • Или любой другой WEB server, который будет обрабатывать HTTP запросы.


      Простой пример - get()

      Простой пример использования метода get() Http клиента - файл на локальном диске, который содержит данные в формате JSON.

      Создадим айл с именем: myData.json

      [ {"Name": "Bob", "Age": "23", "Course": "WEB"}, {"Name": "Anna", "Age": "33", "Course": "PHP"}, {"Name": "Yony", "Age": "27", "Course": "Angular"} ]

      Расположим его в папке src/assets/data

      Создадим компонент get-data

      import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-get-data', templateUrl: './get-data.component.html', styleUrls: ['./get-data.component.css'] }) export class GetDataComponent implements OnInit { fileData: any; constructor(private myHttp: HttpClient) { } ngOnInit( ) { this.myHttp.get('assets/data/myData.json').subscribe( (reslt) => { console.log(this.fileData = reslt) }); } }


      this.myHttp - наш объект типа HttpClient

      this.myHttp.get('assets/data/myData.json') - метод get() этого объекта, который получает в качестве рапаметра - URL , где расположен источник данных в формате JSON

      Этот метод возвращает в качестве результата Angular объект типа Observable. Это - массив данных, элементв которого формируются асинхронно, динамически, в результате запроса.

      У этого объекта есть метод - subscribe(), который позволяет получать данные в формате JSON.

      Мы задали (в формате arrow - function) параметр этого меода - функцию с аргументом reslt, которая выполнится по эго окончании (call-back function). В переменную reslt subscribe поместит результат выполнения.

       this.myHttp.get('assets/data/myData.json').subscribe((reslt) => {console.log(reslt)});

      Этот результат можно запомнить в переменной класса и использовать в шаблоне компонента (при интерпретации данных в примере используется Angular pipe - json для форматирования данных ).

      Шаблон:

      {{fileData | json }}


      this.myHttp.get('assets/data/myData.json').subscribe((reslt) => {console.log(this.fileData = reslt)});


      Результат: 


      PHP - server side

      Далее , для тестирования используем на сервере PHP - программу (myAngularGetV2.php).

      Программа на PHP запущена локально (URL =  http://angularhttp/myAngularGetV2.php).

      Программа получает запрос от Angular и отвечает на него.

      Рассмотрим метод HttpClient.get().


      Код программы:

      <?php header('Access-Control-Allow-Origin: http://localhost:4200'); header('Content-type: application/json'); header('Access-Control-Allow-Methods: GET'); $outstr = ' [ {"Name": "Bob", "Age": "23", "Course": "WEB"}, {"Name": "Anna", "Age": "33", "Course": "PHP"}, {"Name": "Yony", "Age": "27", "Course": "Angular"} ] '; echo($outstr); ?>


      Эта программа получает запрос от Angular - приложения и отдаёт ему нужные данные (данные эти в нашем случае хранятся в переменной $outstr, в реальной жизни, скорее всего PHP берёт их из базы данных)

      Результат - такой же, как при чтении из файла на диске.


      Передача данных от Angular на сервер по get()

      Усложним немного запрос от Angular к серверу.

      Для этого в метод get() добавим ещё один допустимый параметр - params и передадим через него на сервер имя пользователя.

      Вызов get() примет вид:

      this.myHttp.get( myUrl, {params: { 'Name': 'Anna' }} ).subscribe( (reslt) => {console.log(this.fileData = reslt)} ); }

      Мы передаём теперь на сервер по методу get параметр Name со значением Anna

      Теперь сервер получает запрос с параметром. PHP - программа на сервере может этот запрос проанализиолвать и дать ответ в соответствии с этим параметром.

      В нашем случае заведём в программе массив данных - $students и в этом массиве найдём того, чьё имя соответствует параметру запроса.

      В ответ сервера (JSON ) вставим данные только найденного студента.


      PHP:

      <?php header('Access-Control-Allow-Origin: http://localhost:4200'); header('Content-type: application/json'); header('Access-Control-Allow-Methods: GET'); $stud = $_GET['Name']; $students = Array( Array("Name"=> "Bob", "Age"=> "23", "Course"=> "WEB"), Array("Name"=> "Anna", "Age"=> "33", "Course"=> "PHP"), Array("Name"=> "Yony", "Age"=> "27", "Course"=> "Angular"), ); foreach($students as $student){ if($student['Name'] == $stud){ $outstr = '[{ '; $outstr .= '"Name": "'; $outstr .= $student['Name']; $outstr .= '", "Age": "'; $outstr .= $student['Age']; $outstr .= '", "Course": "'; $outstr .= $student['Course']; $outstr .= '" }]'; } } echo($outstr); ?>


      В переменную $stud получили искомого студента

      В цикле foreach перебираем массив, ищем нужного.

      Если нашли - формируем строке $outstring ответ в формате JSON и командой echo отправляем ответ (до этого функциями header мы сформировали необходимый набор HTTP заголовков ).


      Компонент:

      import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-get-data', templateUrl: './get-data.component.html', styleUrls: ['./get-data.component.css'] }) export class GetDataComponent implements OnInit { fileData: any; constructor(private myHttp: HttpClient) { } ngOnInit( ) { const: myUrl = 'http://angularhttp/myAngularGetV2.php'; this.myHttp.get( myUrl, {params: { 'Name': 'Anna' }} ).subscribe( (reslt) => {console.log(this.fileData = reslt)} ); } }


      Шаблон (используем Angular - pipe json для ворматирования данных):

      {{ getData | json }}


      Результат



  • Angular 6 HTTP запросы (part2)

    Структура проекта

    my-post.service.ts - сервис, который обменивается данными с сервером

    my-post-interface.ts - структура данных 

    my-post.component.ts - компонент, который этот сервис использует


    Сервис (Injectable )

    import { Injectable, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MyPostInterface } from './my-post-interface'; @Injectable({ providedIn: 'root' }) export class MyPostService { myData = []; myUrl = 'http://angularhttp/myAngularPostV4.php'; constructor(private myHttp: HttpClient) { } sendRequest() { this.myHttp.post(this.myUrl, {observe: 'body', responseType: 'json'}) .subscribe({ next: data => console.log('Request N: ' , this.myData.push(data)), error: err => console.error('Error: ' + err), complete: () => console.log('Complete'),}); return this.myData; } }


    Интерфейс

    export interface MyDataInterface { id: number; name: string; title: string; msg: string; }


    Компонент

    import { Component, OnInit } from '@angular/core'; import { MyPostService } from '../my-post.service'; @Component({ selector: 'app-my-post', templateUrl: './my-post.component.html', styleUrls: ['./my-post.component.css'] }) export class MyPostComponent implements OnInit { myDataArray = []; constructor(private connectToServer: MyPostService) { } ngOnInit() { } getData() { this.myDataArray = this.connectToServer.sendRequest(); } }


    app-module

    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HttpClientModule } from '@angular/common/http' import { MyPostService } from './my-post.service'; import { MyPostComponent } from './my-post/my-post.component'; @NgModule({ declarations: [ AppComponent, MyPostComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [MyPostService], bootstrap: [AppComponent] }) export class AppModule { }


    Шаблон компонента


    import { Component, OnInit } from '@angular/core'; import { MyPostService } from '../my-post.service'; @Component({ selector: 'app-my-post', templateUrl: './my-post.component.html', styleUrls: ['./my-post.component.css'] }) export class MyPostComponent implements OnInit { myDataArray = []; constructor(private connectToServer: MyPostService) { } ngOnInit() { } getData() { this.myDataArray = this.connectToServer.sendRequest(); } }


    Стили компонента


    TABLE { border-collapse: collapse; width: 100%; } TABLE TH { color: red; font-size: 1.2rem; } TABLE TH, TABLE TD { border: 1px solid lightgray; padding: 5px; } .testbutton { color: #14396A; text-shadow: 1px 1px 0px #7CACDE; box-shadow: 1px 1px 1px #BEE2F9; padding: 10px 25px; border-radius: 10px; border: 2px solid #3866A3; background: #63B8EE; background: linear-gradient(to bottom, #63B8EE, #468CCF); } .testbutton:hover { color: #F00; background: #468CCF; background: linear-gradient(to bottom, #468CCF, #63B8EE); }



    Результат - до запроса к серверу



    После запроса


    Поиск данных на сервере

    Пошлём серверу имя пользователя (Anna), чтобы получить полную информации о нём

    Сервис

    import { Injectable, OnInit } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { MyPostInterface } from './my-post-interface'; @Injectable({ providedIn: 'root' }) export class MyPostService { constructor(private myHttp: HttpClient) { } sendRequest() { const myUrl = 'http://angularhttp/myAngularPostV4.php'; let myData = []; this.myHttp.post(myUrl, {observe: 'body', responseType: 'json'}) .subscribe({ next: data => console.log('Server requested: ' , myData.push(data)), error: err => console.error('Error: ' + err), complete: () => console.log('Complete'),}); return myData; } getUserData() { const myUrl = 'http://angularhttp/myAngularPostV5.php'; const myHeaders = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); let myData = []; this.myHttp.post(myUrl, {name : 'Anna'}, {headers: myHeaders, observe: 'body', responseType: 'json'}) .subscribe({ next: data => console.log('Server requested: ' , myData.push(data)), error: err => console.error('Error: ' + err), complete: () => console.log('Complete'),}); return myData; } }



    Компонент

    import { Component, OnInit } from '@angular/core'; import { MyPostService } from '../my-post.service'; @Component({ selector: 'app-my-post', templateUrl: './my-post.component.html', styleUrls: ['./my-post.component.css'] }) export class MyPostComponent implements OnInit { allUsers = []; foundUser = []; constructor(private connectToServer: MyPostService) { } ngOnInit() { } getAllData() { this.allUsers = this.connectToServer.sendRequest(); } getUserData() { this.foundUser = this.connectToServer.getUserData(); } }



    Шаблон компонента

    <h1>POST test component</h1> <hr> <button class='testbutton' (click)='getAllData()'>Request all data from server</button> <table> <tr> <th>ID</th> <th>Name</th> <th>Position</th> <th>Remarks</th> </tr> <tr *ngFor='let str of allUsers[0]'> <td>{{str['id']}}</td> <td>{{str['name']}}</td> <td>{{str['title']}}</td> <td>{{str['msg']}}</td> </tr> </table> <hr> <button class='testbutton' (click)='getUserData()'>Get user data</button> <table> <tr> <th>ID</th> <th>Name</th> <th>Position</th> <th>Remarks</th> </tr> <tr *ngFor='let str of foundUser[0]'> <td>{{str['id']}}</td> <td>{{str['name']}}</td> <td>{{str['title']}}</td> <td>{{str['msg']}}</td> </tr> </table> <hr>



    app.module.ts
    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HttpClientModule } from '@angular/common/http' import { MyPostService } from './my-post.service'; import { MyPostComponent } from './my-post/my-post.component'; @NgModule({ declarations: [ AppComponent, MyPostComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [MyPostService], bootstrap: [AppComponent] }) export class AppModule { }


    Результат 



    Server side

    Используется  Apache на локальном компьютере. Адрес сервера: http://angularhttp/ Запросы обрабатывает PHP - программа myAngularPostV4.php.

    Формат данных и способ их интерпретации зависит от HTTP заголовков (руфвукы), которые выставлены и в Angular 

    const myHeaders = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

    и 

    {observe: 'body', responseType: 'json'}

    и в PHP

    header('Content-type: application/x-www-form-urlencoded; charset=UTF-8');

    PHP должен интерпретировать то, что посылает Angular через метод subscribe() объекта Observable. Если при посылке меняем формат, то и в PHP его надо менять.


    Программа PHP получает запрос от Angular и в ответ посылает строку с данными (в формате JSON) - myAngularPostV4.php

    <?php header('Access-Control-Allow-Origin: http://localhost:4200'); header('Content-type: application/json'); header("Access-Control-Allow-Headers: *"); header('Access-Control-Allow-Methods: POST'); $outstr = '[{ "id" : 1000, "name" : "Anna", "title" : "Manager", "msg" : "Sales department" }, { "id" : 1001, "name" : "Bob", "title" : "Technician", "msg" : "Server support team" }, { "id" : 1002, "name" : "Alex", "title" : "WEB developer", "msg" : "Corporate web development team" } ]'; echo($outstr); ?>



    Эхо - тест (получили запрос - отдали то, что получили) - myAngularPostV3.php

    <?php header('Access-Control-Allow-Origin: http://localhost:4200'); header('Content-type: application/json'); header("Access-Control-Allow-Headers: *"); header('Access-Control-Allow-Methods: POST'); $_POST = json_decode(file_get_contents('php://input'), true); $id = $_POST['id']; $name = $_POST['name']; $title = $_POST['title']; $msg = $_POST['msg']; $outstr = '[{ '; $outstr .= '"id": "'; $outstr .= $id; $outstr .= '", "name": "'; $outstr .= $name; $outstr .= '", "title": "'; $outstr .= $title; $outstr .= '", "msg":"'; $outstr .= $msg; $outstr .= '" }]'; echo($outstr); ?>


    Найти пользователя по имени (myAngularPostV5.php)


    <?php //if($_SERVER['HTTP_ORIGIN'] == "http://localhost:4200") header('Access-Control-Allow-Origin: http://localhost:4200'); header("Access-Control-Allow-Headers: *"); header('Content-type: application/x-www-form-urlencoded; charset=UTF-8'); header('Access-Control-Allow-Methods: POST'); $data = json_decode(file_get_contents("php://input")); $name = $data->name; $users = Array(); $users[] = Array ("id"=> 1111, "name"=> "Bob", "title"=> "Manager", "msg"=> "CEO"); $users[] = Array("id"=> 222, "name"=> "Nik", "title"=> "Sales", "msg"=> "Corporate sales dept"); $users[] = Array("id"=> 4444, "name"=> "Anna", "title"=> "Technician", "msg"=> "Network support team"); $users[] = Array("id"=> 5, "name"=> "Haim", "title"=> "HR", "msg"=> "Human resource"); $users[] = Array("id"=> 76, "name"=> "Ronald", "title"=> "CA", "msg"=> "Accounting") ; foreach($users as $key => $user){ if($user['name'] == $name){ $outstr = '[{ '; $outstr .= '"id": "'; $outstr .= $user['id']; $outstr .= '", "name": "'; $outstr .= $user['name']; $outstr .= '", "title": "'; $outstr .= $user['title']; $outstr .= '", "msg": "'; $outstr .= $user['msg']; $outstr .= '" }]'; } } error_log( $outstr); echo($outstr); ?>



    Асинхронный поиск по мере ввода имени

    В этом примере в окне браузера (в поле INPUT ) вводится имя сотрудника. По мере ввода (событие - keyup ) имя пересылается по POST серверу и проверяется PHP программой на сервере. Если PHP не нашёл сотрудника по имени (ищем в массиве сотрудников), он выдаёт сообщение (также в формате JSON)  

    Сервис


    import { Injectable, OnInit } from '@angular/core'; import { HttpClient, HttpHeaders} from '@angular/common/http'; import { MyPostInterface } from './my-post-interface'; import { PostOptionsInterface } from './post-options-interface'; @Injectable({ providedIn: 'root' }) export class MyPostService { constructor(private myHttp: HttpClient) { } sendRequest() { const myUrl = 'http://angularhttp/myAngularPostV4.php'; let myData = []; this.myHttp.post(myUrl, {observe: 'body', responseType: 'json'}) .subscribe({ next: data => console.log('Server request: ' , myData.push(data)), error: err => console.error('Error: ' + err), complete: () => console.log('Complete'),}); return myData; } getSingleUser() { const myUrl = 'http://angularhttp/myAngularPostV5.php'; const myHeaders = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); let myData = []; this.myHttp.post(myUrl, {name : 'Anna'}, {headers: myHeaders, observe: 'body', responseType: 'json'}) .subscribe({ next: data => console.log('Server request: ' , myData.push(data)), error: err => console.error('Error: ' + err), complete: () => console.log('Complete'),}); return myData; } findUser(userName){ const httpHdr = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); const postUrl = 'http://angularhttp/myAngularPostV6.php'; const postBody = {name : userName}; let myData = []; this.myHttp.post(postUrl, postBody, { headers: httpHdr, observe: 'body', responseType: 'json' }) .subscribe({ next: data => console.log('Server requested: ' , myData.push(data)), error: err => console.error('Error: ' + err), complete: () => console.log('Complete'),}); return myData; } }


    Компонент


    import { Component, OnInit } from '@angular/core'; import { MyPostService } from '../my-post.service'; @Component({ selector: 'app-my-post', templateUrl: './my-post.component.html', styleUrls: ['./my-post.component.css'] }) export class MyPostComponent implements OnInit { allUsers = []; singleUser = []; foundUser = []; constructor(private connectToServer: MyPostService) { } ngOnInit() { } getAllData() { this.allUsers = this.connectToServer.sendRequest(); } getSingleUser() { this.singleUser = this.connectToServer.getSingleUser(); } findUser(evnt){ console.log(evnt.target.value); this.foundUser = this.connectToServer.findUser(evnt.target.value); } removeHint(evnt){ evnt.target.value = ''; evnt.target.select(); } }


    HTML - шаблон компонента


    <h1>POST test component</h1> <hr> <button class='testbutton' (click)='getAllData()'>Request all users data from server</button> <table> <tr> <th>ID</th> <th>Name</th> <th>Position</th> <th>Remarks</th> </tr> <tr *ngFor='let str of allUsers[0]'> <td>{{str['id']}}</td> <td>{{str['name']}}</td> <td>{{str['title']}}</td> <td>{{str['msg']}}</td> </tr> </table> <hr> <button class='testbutton' (click)='getSingleUser()'>Get data of user: Anna</button> <table> <tr> <th>ID</th> <th>Name</th> <th>Position</th> <th>Remarks</th> </tr> <tr *ngFor='let str of singleUser[0]'> <td>{{str['id']}}</td> <td>{{str['name']}}</td> <td>{{str['title']}}</td> <td>{{str['msg']}}</td> </tr> </table> <hr> <input type='text' (keyup)='findUser($event)' (mouseenter)='removeHint($event); ' name='' value='Type case-sensitive user name here...'> <table> <tr> <th>ID</th> <th>Name</th> <th>Position</th> <th>Remarks</th> </tr> <tr *ngFor='let str of foundUser[0]'> <td colspan=4 *ngIf="str['id'] == 0; else found">{{str['name']}} {{str['title']}} {{str['msg']}}</td> <ng-template #found> <td>{{str['id']}}</td> <td>{{str['name']}}</td> <td>{{str['title']}}</td> <td>{{str['msg']}}</td> </ng-template> </tr> </table> <hr>



    CSS - стили компонента



    BUTTON, INPUT { margin: 10px 0px; } INPUT { width: 98.5%; padding: 5px; background-color: #EFEFEF; } TABLE { border-collapse: collapse; width: 100%; } TABLE TH { color: red; font-size: 1.2rem; } TABLE TH, TABLE TD { border: 1px solid lightgray; padding: 5px; } .testbutton { color: #FFF; text-shadow: 1px 1px 0px #7CACDE; box-shadow: 1px 1px 1px #BEE2F9; padding: 10px 25px; border-radius: 10px; border: 2px solid #3866A3; background: #63B8EE; background: linear-gradient(to bottom, #63B8EE, #468CCF); } .testbutton:hover { color: #F00; background: #468CCF; background: linear-gradient(to bottom, #468CCF, #63B8EE); }



    app.module.ts


    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HttpClientModule } from '@angular/common/http' import { MyPostService } from './my-post.service'; import { MyPostComponent } from './my-post/my-post.component'; @NgModule({ declarations: [ AppComponent, MyPostComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [MyPostService], bootstrap: [AppComponent] }) export class AppModule { }




    Интерфес - структура данных: my-post-interface.ts

    export interface MyPostInterface { id: number; name: string; title: string; msg: string; }



    Server side: PHP - ищет сотрудника по имени (http://angularhttp/myAngularPostV6.php)

    <?php // if($_SERVER['HTTP_ORIGIN'] == "http://localhost:4200") header('Access-Control-Allow-Origin: http://localhost:4200'); header('Content-type: application/x-www-form-urlencoded; charset=UTF-8'); header('Access-Control-Allow-Methods: POST'); $data = json_decode(file_get_contents("php://input")); $name = $data->name; $users = []; $users[] = ["id"=> 1111, "name"=> "Bob", "title"=> "Manager", "msg"=> "CEO"]; $users[] = ["id"=> 222, "name"=> "Nik", "title"=> "Sales", "msg"=> "Corporate sales dept"]; $users[] = ["id"=> 4444, "name"=> "Anna", "title"=> "Technician", "msg"=> "Network support team"]; $users[] = ["id"=> 5, "name"=> "Haim", "title"=> "HR", "msg"=> "Human resource"]; $users[] = ["id"=> 76, "name"=> "Ronald", "title"=> "CA", "msg"=> "Accounting"] ; $outstr = '[{ "id":"00000", "name":"User", "title":"not", "msg":"found" }]'; foreach($users as $key => $user){ if($user['name'] == $name){ $outstr = '[{ '; $outstr .= '"id": '; $outstr .= $user['id']; $outstr .= ', "name": "'; $outstr .= $user['name']; $outstr .= '", "title": "'; $outstr .= $user['title']; $outstr .= '", "msg": "'; $outstr .= $user['msg']; $outstr .= '" }]'; } } error_log($name); error_log( $outstr); echo($outstr); ?>


    Server side: PHP выводит всех сотрудников ((http://angularhttp/myAngularPostV4.php))


    <?php header('Access-Control-Allow-Origin: http://localhost:4200'); header('Content-type: application/x-www-form-urlencoded; charset=UTF-8'); header("Access-Control-Allow-Headers: *"); header('Access-Control-Allow-Methods: POST'); $users = []; $users[] = ["id"=> 1111, "name"=> "Bob", "title"=> "Manager", "msg"=> "CEO"]; $users[] = ["id"=> 222, "name"=> "Nik", "title"=> "Sales", "msg"=> "Corporate sales dept"]; $users[] = ["id"=> 4444, "name"=> "Anna", "title"=> "Technician", "msg"=> "Network support team"]; $users[] = ["id"=> 5, "name"=> "Haim", "title"=> "HR", "msg"=> "Human resource"]; $users[] = ["id"=> 76, "name"=> "Ronald", "title"=> "CA", "msg"=> "Accounting"] ; $outstr = json_encode($users, JSON_PRETTY_PRINT); echo($outstr); ?>


    Результат - вывели всех сотрудников




    Результат при начале набора в поле ввода




    Результат - нашлось имя



    PHP - error log (при каждом событии keyup PHP получает имя и пишет для отладки в error log полученное имя и строку для отправки в Angular ):

    [01-Jun-2018 15:43:53 UTC] R [01-Jun-2018 15:43:53 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }] [01-Jun-2018 15:43:53 UTC] R [01-Jun-2018 15:43:53 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }] [01-Jun-2018 15:43:54 UTC] Ron [01-Jun-2018 15:43:54 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }] [01-Jun-2018 15:43:54 UTC] Ron [01-Jun-2018 15:43:54 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }] [01-Jun-2018 15:43:54 UTC] Rona [01-Jun-2018 15:43:54 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }] [01-Jun-2018 15:43:55 UTC] Ronal [01-Jun-2018 15:43:55 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }] [01-Jun-2018 15:43:55 UTC] Ronald [01-Jun-2018 15:43:55 UTC] [{ "id": 76, "name": "Ronald", "title": "CA", "msg": "Accounting" }]









  • Angular 6 routing

    Angular - навигация по сайту (Angular routing)

    При помощи  Routing - модуля Angular позволяет организовать привычную навигацию по страничкам сайта:

    • если ввести в адресной строке браузера IRI нужной странички, то она откроется
    • если кликнуть по ссылке на нужную страничку сайта (меню сайта, другие внутренние ссылки) , то Angular откроет её в окне браузера
    • если пользоваться кнопками браузера НАЗАД, ВПЕРЁД, то мы будем перемещаться по истории посещённых страничек сайта.

    Сконфигурируем сайт, который будет состоять из: одной главной странички - home, страничек  About, Contacts и специальной странички, которая будет открываться в том случае, если посетитель сайта пытается перейти на несуществующую страничку - NotFound.

    Для этого:

    • генерируем новый проект с опцией - routing (ng new routing-test1 --routing) в дополнение к стандарной конфигурации проекта появится модуль app-routing.module.ts
    • генерируем модуль с названием header для меню сайта
    • генерируем модули для каждой нужной странички сайта (home, about, contacts, notFound)
    • проверяем наличие тега <base href="/"> в файле index.html, что обязательно для работы router 
    • конфигурируем router - модуль (ссылки и их привязки к компонентам)
    • конфигурируем шаблон сайта в модуле app.component

    Angular создаёт app-routing.module.ts

    import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = []; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }


    Генерируем нужные компоненты:

    ng g c not-found

    ng g c contacts

    ng g c home

    ng g c header

    ng g c about


    Все компоненты и Router импортированы в app.module - проверяем:

    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; import { HeaderComponent } from './header/header.component'; import { AboutComponent } from './about/about.component'; import { ContactsComponent } from './contacts/contacts.component'; import { NotFoundComponent } from './not-found/not-found.component'; @NgModule({ declarations: [ AppComponent, HomeComponent, HeaderComponent, AboutComponent, ContactsComponent, NotFoundComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }


    Конфигурируем - app.component

    import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { }


    Его HTML шаблон:

    <div id='wrapper'> <app-header></app-header> <router-outlet></router-outlet> </div>

    Через него определяем место (placeholder ) в окне браузера для компонента-меню (<app-header></app-header>)

    И для меняющихся компонентов-страничек ( <router-outlet></router-outlet>)

    Его стили:

    #wrapper { display: grid; grid-template-rows: auto auto; grid-template-columns: 1fr; }


    Компоненты страничек практически ничем, в нашем примере, друг от друга не отличаются (только текстом в HTML).

    import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-about', templateUrl: './about.component.html', styleUrls: ['./about.component.css'] }) export class AboutComponent implements OnInit { constructor() { } ngOnInit() { } }


    HTML

    <h1>About Us</h1>


    Компонент header - это меню сайта (он показывает кнопки меню и привязывает их к тем путям URI , которые мы задали в раутере, он появляется на каждой страничке):

    import { Component} from '@angular/core'; @Component({ selector: 'app-header', templateUrl: './header.component.html', styleUrls: ['./header.component.css'] }) export class HeaderComponent { constructor() { } }


    HTML

    Директивы routerLink привязывают тег A к пути, который задан в модуле Router (константа routes )

    Директивы routerLinkActive присваивают элементам A класс стилей myActive в тот момент, когда ссылка активна.

    <div id='navBlock'> <a class='menuItem' routerLink='/home' routerLinkActive="myActive">Home</a> <a class='menuItem' routerLink='/about' routerLinkActive="myActive">About</a> <a class='menuItem' [routerLink]="['/contacts']" routerLinkActive="myActive">Contacts</a> </div>


    Стили

    Селектор  .menuItem[class*='myActive'] описывает стиль для активной ссылки. Класс myActive она получает по директиве routerLinkActive

    #navBlock { display: grid; grid-template-columns: repeat(3, minmax(auto, 300px)); grid-template-rows: 1fr; justify-content: center; align-content: space-between; border-bottom: 1px solid #aaa; } .menuItem { display: inline-block; text-align: center; padding: 10px 0px; margin: 10px; border: 1px solid #FFF; font-weight: bold; font-size: 1.2re; border-radius: 5px; box-shadow: 0px 2px 5px 1px rgba(100, 100, 100, 0.294); } .menuItem:hover { border-color: red; box-shadow: 0px 5px 10px 3px rgba(100, 100, 100, 0.294); } .menuItem[class*='myActive'] { color: red ! important; } .menuItem:visited { color: blue; } A { text-decoration: none; }




    Конфигурируем router.

    Конфигурируем в константе routes массив ссылок. Каждый элемент массива - путь и компонент, который к этому пути привязан.

    Элемент массива {path: '', redirectTo: '/home', pathMatch: 'full'} переадресовывает ссылки в корень сайта на страничку home

    Элемент массива {path: '**', component: NotFoundComponent} переадресовывает все странички, путь к которым не соответствует фильтрам пути в предыдущих элементах, на страничку NotFound 

    import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { AboutComponent } from './about/about.component'; import { ContactsComponent } from './contacts/contacts.component'; import { HomeComponent } from './home/home.component'; import { NotFoundComponent } from './not-found/not-found.component'; const routes: Routes = [ {path: '', redirectTo: '/home', pathMatch: 'full'}, {path: 'home', component: HomeComponent}, {path: 'about', component: AboutComponent}, {path: 'contacts', component: ContactsComponent}, {path: '**', component: NotFoundComponent} ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }



    Результат :





  • Angular 6 service

    Angular Service


    Angular service - это специализированный компонент, который предназначен для того, чтобы предоставлять другим компонентам какие-либо общие данные.

    Генерируем сервис, пользуясь Angular CLI

    ng g service my-serv1

    Получаем его шаблон:  

    import { Injectable } from '@angular/core'; @Injectable() export class MyServ1Service { constructor() { } }


    Импортируем его в app.module.ts, чтобы он был доступен всем компонентам проекта

    import { MyServ1Service } from './my-serv1.service';

    Регистрируем его там же в providers, чтобы можно было его использовать во всех дочерних компонентов через Angular Dependancy Injection

    providers: [ MyServ1Service ],

     


    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { CollapseModule } from 'ngx-bootstrap/collapse'; import { PopoverModule } from 'ngx-bootstrap/popover'; import { AppComponent } from './app.component'; import { Comp1Component } from './comp1/comp1.component'; import { MyServ1Service } from './my-serv1.service'; @NgModule({ declarations: [ AppComponent, Comp1Component ], imports: [ PopoverModule.forRoot(), CollapseModule.forRoot(), BsDropdownModule.forRoot(), BrowserModule ], providers: [ MyServ1Service ], bootstrap: [AppComponent] }) export class AppModule { }




    Добавляем метод getSomething():  

    import { Injectable } from '@angular/core'; @Injectable() export class MyServ1Service { constructor() { } getSomething(){ return "222222222"; } }



    Используем в компоненте - без Dependancy injection (не рекомендуется)

    import {MyServ1Service} from '../my-serv1.service' ; import { Component} from '@angular/core'; @Component({ selector: 'comp1', template: ` <h1>Comp1Component</h1> {{courses}} ` }) export class Comp1Component { courses; constructor (){ let servData = new MyServ1Service(); this.courses = servData.getSomething(); } }



    Используем в компоненте через Dependency injection (в этом случае constructor (service: MyServ1Service) создаёт внутри класса переменную с именем service , которая является объектом (instance) класса MyServ1Service )

    import {MyServ1Service} from '../my-serv1.service' ; import { Component} from '@angular/core'; @Component({ selector: 'comp1', template: ` <h1>Comp1Component</h1> {{courses}} ` }) export class Comp1Component { courses; constructor (service: MyServ1Service){ this.courses = service.getSomething(); } }


    И в app.module.ts добавляем импорт 

    import { MyServ1Service } from './my-serv1.service';

    и 

    providers: [ MyServ1Service ],


    весь файл 

    import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { CollapseModule } from 'ngx-bootstrap/collapse'; import { PopoverModule } from 'ngx-bootstrap/popover'; import { AppComponent } from './app.component'; import { Comp1Component } from './comp1/comp1.component'; import { MyServ1Service } from './my-serv1.service'; @NgModule({ declarations: [ AppComponent, Comp1Component ], imports: [ PopoverModule.forRoot(), CollapseModule.forRoot(), BsDropdownModule.forRoot(), BrowserModule ], providers: [ MyServ1Service ], bootstrap: [AppComponent] }) export class AppModule { }






  • WEB - Основы современных интернет-технологий

    Основы современных интернет-технологий

    Введение

    Интернет сегодня - это всемирная сеть, которая объединяет миллионы компьютеров, расположенных в разных частях света. Функционирование этой сети обеспечивает организация  ISOC (The Internet Society) - это американская некоммерческая организация (Reston, Virginia, U.S.), основанная в 1992 году. Штаб-квартира ISOC  находится в городе Рестон, Вирджиния, США , ISOC имеет фиоиалы  в Женеве, Швейцария. Члены ISOC -  более чем 140 организаций и более 80 000 индивидуальных членов. 

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

    Набор этих правил регламентируется и публикуются организацией - IETF ( Internet Engineering Task Force - Fremont, California, United States). Эти стандарты (интернет-протоколы - TCP/IP stack) публикутся в форме специальных документов - RFC (Requests For Comments), которые общедоступны.

    В пространстве Интернет можно выделить компьютеры, на которых установлены специальные программы которые   умеют предоставлять различные Интернет-услуги. Они называются Серверами (Server). Так, например, на каком-то компьютере может быть установлен WEB сервер ( Apacheб IIS,... ). В этом случае компьютер сможет публиковать в Интернет WEB - сайты.

    На других компьютерах, которые тоже входят в Интернет, могут стоять специальные программы, которые умеют полцчать определённый тип услуг - клиенты. Например, программы типа Chrome, IE, Opera и другие браузеры умеют запрашивать у WEB серверов WEB странички и показывать их на экране компьютера.

    Протоколы TCP/IP

    Подробное описание стека протоколов TCP/IP выходит за рамки нашего обсуждения. 

    Для WEB - разработчика достаточно иметь общее представленте о некоторых из них.

    Протоколы TCP (Transmission Control Protocol), IP (Internet Protocol) обеспечивают адресацию компьютеров в пространстве Интарнет, доставку пакетов (единицу информации). Каждому компьютеру в Интернет присваивается уникальный адрес IP, состоящий из 4-х наборов цифр. Например адрес 8.8.8.8 принадлежит DNS серверу Google.

    Распределением этих адресов занимается InterNic (International Network Information Center).

    Протокол DNS. 

    Для удобства использования Интернет-адресов их цифровые значения часто заменяют на более читабельные текстовые адреса - DNS -  имена. Специальные сервера (DNS - Server) поддерживают в пространстве Интернет распеделённую иерархическую базу данных DNS имён. 

    Основная задача этой базы данных - приводить в соответсвие   цифровые IP - адреса текстовым DNS именам. Для общения компьютеров в Интенет необходимы именно цифровые IP адреса. 

    Протокол DND даёт пользователям возможность не запоминать цифры, а запоминать дружественные текстовые имена в качестве адресов в Интернет.

    Пространство DNS имён представляет собой дерево. От корня этого дерева имён отходят ветки - домены верхнего уровня. У каждого из них есть дочерние втки - домены следующих уровней. Распределением DNS имён и поддержкой доменов верхнего уровня - TLD (Top Level Domains) занимается ICANN   (Internet Corporation for Assigned Names and Numbers). Управление доменами следующих подуровней делегировано другим организациям.

    Протокол FTP позволяет обмениваться файлами через Интернет.

    Протоколы POP, SMTP, IMAP позволяют обмениваться почтовыми сообщениями.

    Протокол HTTP описывает правила взаимодействия WEB сервера с его клиентом - браузером.


    Разработка WEB сайтов

    Стандарты для разработчиков WEB регулируются организацией W3C  (World Wide Web Consortium).

    Это, например, CGI, CSS, DOM, HTML.

    • Технологии Front-end, Back-end. 
    • WEB страница. WEB сайт. Принципы построения и функционирования.


    Основные этапы построения сайта

    • Планирование сайта, выбор и регистрация имени домена.
    • Контент сайта. Планирование и подготовка содержимого сайта.
    • Дизайн сайта. Проработка логики построения сайта. Разработка схемы навигации. Меню.
    • Разработка графического дизайна. Выбор платформы сайта. Создание сайта.
    • Выбор хостинга. Размещение сайта на WEB – хостинге. 
    • Тестирование сайта.
    • Оптимизация сайта. Теги META, Ссылки сайта (SEF). Карта сайта (sitemap). Подготовка для поисковых роботов. Регистрация в поисковиках. SEO. Аналитика, продвижение сайта в интернет.


    Программирование для WEB

    • WEB - сервера. WEB - браузеры. Обзор языков HTML, JavaScript, PHP

     

    Записаться на курс

     



  • Web developer

    Современные интернет-технологии

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

    • Графический дизайн интерфейса сайта (WEB design, UI design )
    • Разработка функциональных возможностей сайта (Front-end development, UX design и Back-end development)

    В зависимости от деталей реализации каждого конкретного интерет-проекта: его целей, сложности, бюджета может отпасть необходимость какого-либо конкретного этапа разработок.

    Так, например, какие-то проекты могут обойтись без авторского дизайна, а для каких-то проектов не потребуется сложная структура управления базаими данных.

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

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

    Все наши программы обучения ориентированы, в первую очередь, на требования современного рынка труда.

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

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

    WEB дизайнер

    (WEB designer, UI/UX designer)

    Курс рассчитан на подготовку специалистов по разработке графического интерфейса для интернет-проектов.

    Это: графический дизайн сайта, создание шаблонов, подготовка и оптимизация графического контента (картинки, mutimedia).

    Предварительные требования

    • Опыт работы с компьютером и интернет в качестве пользователя (интерфейс Windows или Linux, интернет браузер, текстовый редактор)

    Программа курса

    Adobe Photoshop, Illustrator, Dreamweaver - basics

    HTML5, CSS3, FlexBox, CSS grid

    Bootstrap 4 - CSS

    WEB - разработчик (интерфейс пользователя)

    (Front-end, Client-side developer)

    Курс рассчитан на подготовку специалистов-разработчиков, специализирующихся на клиентской части интернет-приложений.

    Это: логика и функционал интерфейса сайта - всё то, что выполняется браузером клиента. А также: оптимизация сайта для поисковых машин, интернет-продвижение сайта (CEO).

    Предварительные требования

    • Опыт работы с компьютером и интернет в качестве пользователя (интерфейс Windows или Linux, интернет браузер, текстовый редактор)
    • Базовые знания Английского языка (на уровне технического перевода)

    Программа курса

    Акад. часов - в группеАкад. часов - индивидуально
    1HTML5, CSS3, FlexBox, CSS grid 6010
    2Browser, DOM, JavaScript 60 10
    3jQuery, jQuery UI 406
    4Bootstrap 4 - CSS, Bootstrap 4 - jQuery 305
    5NodeJS, MS TypeScript, SASS 305
    6Angular 5 framework 5510
    7CEO 152
    Всего 31035

    WEB - разработчик (серверные приложения)

    (Back-end, Server-side developer)

    Курс рассчитан на подготовку специалистов-разработчиков, специализирующихся на серверной части интернет-приложений.

    Это: функционирование серверной части интернет-приложения, обработка запросов клиентов, базы данных.

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

    Наиболее распространённые - это сервера Apache на операционной системе Linux. Программирование на PHP, MySQL.

    Предварительные требования

    • Опыт работы с компьютером и интернет в качестве пользователя (интерфейс Windows или Linux, интернет браузер, текстовый редактор)
    • Базовые знания Английского языка (на уровне технического перевода)


    Программа курса - Back-end PHP

    Акад. часов - в группеАкад. часов - индивидуально
    1HTML5, CSS3 508
    2Apache102
    3PHP 7, MySQL10020
    4Laravel 5 Framework 10020
    Всего 30050


    Программа курса - Back-end Java

    Акад. часов - в группеАкад. часов - индивидуально
    1HTML5, CSS3508
    2Apache, Tomcat, Eclipse 407
    3Java 10020
    4Spring MVC10020
    Всего29055


    Программа курса - Back-end Python

    Акад. часов - в группеАкад. часов - индивидуально
    1HTML, CSS, and JavaScript6010
    2Python and Django18040
    Всего24050


    WEB - разработчик (полный курс)

    (Full stack WEB developer )

    Курс готовит универсальных специалистов широкого профиля, охватывая специальности: Front-end и Back-end developer


    WEB - начинаюшим

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

    Это: системы управления контентом (WordPress, Joomla, Opencart), использование готовых шаблонов, создание шаблонов - Artisteer.

    Предварительные требования

    • Опыт работы с компьютером в качестве пользователя

    Программа курса

    Акад. часов - в группе Акад. часов - индивидуально
    1HTML5, CSS3 - intro 305
    2CMS Joomla, WordPress, Opencart 10020
    3Шаблоны сайтов. Artisteer5010
    Всего18035