Эта статья основана на альфа-версии Angular 2, которая сейчас устарела. Актуальное руководство см. В статье Angular 2 Tutorial: создание приложения CRUD с Angular CLI .
Текущая стабильная версия Angular (то есть Angular 1.x) была построена с использованием функций ES5 и предназначалась для работы на большинстве браузеров, включая некоторые из более старых версий IE. Фреймворк должен был создать собственную систему модулей, абстрагировать некоторые языковые функции и обеспечить интерфейс для работы с абстракцией и конфигурацией.
Все хорошие вещи Angular 1 по-прежнему доступны в Angular 2, но рамки проще. Angular 2 построен с учетом особенностей ES6 (и ES7), веб-компонентов и предназначен для вечнозеленых браузеров.
TypeScript — это типизированный супер-набор JavaScript, созданный и поддерживаемый Microsoft и выбранный группой разработчиков AngularJS для разработки. Наличие типов делает код, написанный на TypeScript, менее подверженным ошибкам во время выполнения. В последнее время поддержка ES6 была значительно улучшена, а также были добавлены некоторые функции от ES7.
В этой статье мы увидим, как использовать Angular 2 и TypeScript для создания простого приложения. Поскольку Angular 2 все еще находится в альфа-версии, синтаксис фрагментов кода, показанных в этой статье, может измениться, прежде чем он достигнет стабильной версии. Код, разработанный в этой статье, доступен на GitHub .
Основы Angular 2
Angular 2 был построен с учетом простоты. Команда удалила несколько рецептов Angular 1, которые заставили нас задуматься: «Зачем мы это делаем?» (Если вы хотите узнать, что было удалено, я предлагаю вам взглянуть на это видео под названием « Angular 2.0 Core session» от Igor). и Тобиас ). Теперь структура состоит из небольшого набора строительных блоков и некоторых соглашений, которым необходимо следовать.
Строительные блоки, которые присутствуют в Angular 2:
- Компоненты: Компонент похож на директивы в Angular 1. Он построен с использованием функций веб-компонентов. Каждый компонент имеет представление и часть логики. Он может взаимодействовать со службами для достижения своей функциональности. Сервисы могут быть «внедрены зависимостями» в компонент. Все, что должно использоваться с учетом компонента, должно быть открытым членом в экземпляре компонента. Компоненты используют привязку свойств, чтобы проверять изменения значений и воздействовать на них. Компоненты могут обрабатывать события, а обработчики событий являются открытыми методами, определенными в классе компонента.
- Сервисы: Сервис — это простой класс ES6 с некоторыми аннотациями для внедрения зависимостей.
Как и в Angular 1, Angular 2 использует Dependency Injection для получения ссылок на объекты. Поскольку scope
Следовательно, нам не нужно продолжать вызывать scope.$apply
Angular 2 использует Zone.js для запуска изменений, и эта библиотека знает, когда действовать.
Приложение Angular 2 запускается с компонента, а остальная часть приложения разделена на несколько компонентов, которые загружаются внутри корневого компонента.
Если вы хотите узнать больше об основах Angular 2, ознакомьтесь с публикацией в блоге Виктора Савкина об основных понятиях в Angular 2 .
Настройка
На момент написания этой статьи Angular 2 все еще находится в альфа-версии, поэтому среда и ресурсы вокруг него все еще не обработаны. Они пройдут через ряд изменений и станут лучше к тому времени, когда они будут готовы к производству.
Существует множество начальных проектов, которые можно начать с Angular 2 и TypeScript. Я думаю, что этот Elad Katz мог бы стать хорошей отправной точкой для некоторой практики. Для начала, если вы хотите следовать этому уроку, клонируйте этот репозиторий. Затем следуйте инструкциям, указанным в readme
Репозиторий:
- содержит базовое приложение Angular 2 с использованием TypeScript
- использует JSPM / SystemJS для загрузки зависимостей на страницах
- ссылается на файлы определений TypeScript библиотек, использующих TSD, и определяет отсутствующие определения Angular 2 в локальном файле
angular2.temp.d.ts
- вызывает API Express REST для использования в Angular
- использует Gulp для переноса кода TypeScript на ES5 и запуска сервера Node.js
- содержит исходные файлы TypeScript, которые находятся внутри папки сценариев, а общая папка используется для хранения передаваемых файлов.
Как закрепить ваши достижения
Построение Express API
Теперь, когда у вас есть представление о том, что такое Angular 2, и вы также клонировали начальный проект, давайте изменим его. Мы создадим простое приложение, чтобы закрепить ваши достижения на доске. Прежде всего, давайте добавим Express API для получения и добавления достижений. Когда я разветвил репозиторий и изменил начальный проект, добавив базовые API-интерфейсы Express, вы увидите конечную точку, обслуживающую существующий список всех достижений. Чтобы опубликовать новое достижение, нам нужно добавить конечную точку.
Чтобы выполнить эту первую задачу, откройте файл server.js
app.post('/api/achievements', function(request, response){
achievements.push(JSON.parse(request.body));
response.send(achievements);
});
Поскольку Http
Итак, давайте добавим промежуточное ПО bodyParser
app.use(bodyParser.text({
type: 'text/plain'
}));
Модификация компонента запуска и маршрутов
Файл index.html
Основная часть этого файла загружает скрипт bootstrap
my-app
Этот компонент в свою очередь загружает другие компоненты в приложение. Файл bootstrap.ts загружает приложение AngularJS с использованием основного компонента. Как видите, необходимые функции для инъекций, экспортируемые другими модулями, передаются в функцию. Это делает службы и директивы, экспортируемые этими модулями, доступными для всех дочерних компонентов bootstrap.ts
Мы будем использовать my-app
form
formInjectables
angular2/forms
Компонент запуска проекта находится внутри папки import {formInjectables} from 'angular2/forms';
К компоненту применены две аннотации:
bootstrap(MyApp, [routerInjectables, httpInjectables, formInjectables, AchievementsService]);
- Компонент: содержит свойства конфигурации компонента, такие как селектор, имена свойств, имена событий и список инъекций в компонент. Значение селектора может совпадать со строкой, используемой в разметке HTML, его не нужно обрабатывать верблюдом
- Представление: аннотация представления загружает данные, необходимые для части представления компонента. Он включает в себя шаблон HTML (может быть встроенным или URL-адрес шаблона) и список директив, в которых нуждается компонент
Ниже вы можете увидеть соответствующий код:
app
Компонент @Component({
Сервис
selector: 'my-app'
})
@View({
templateUrl: _settings.buildPath + '/components/app/app.html',
directives: [RouterLink, RouterOutlet]
})my-app
Router
Следующий фрагмент определяет два маршрута, необходимые для приложения:
MyApp
Поскольку компонент добавления еще не добавлен, вы столкнетесь с некоторыми проблемами, если попытаетесь запустить приложение сейчас. Нам нужно создать новую папку внутри папки компонентов и назовите ее export class MyApp {
Затем мы добавляем в эту папку два файла:
constructor(@Inject(Router) router: Router) {
router.config([
{ path: '', as: 'home', component: Home },
{ path: '/add', as: 'add', component: Add }
]);
}
}add
add
Наконец, добавьте следующий фрагмент в add.ts
add.html
Представление этого компонента будет иметь форму, принимающую входные данные для сохранения в качестве нового достижения. Итак, добавьте следующий HTML-код на эту страницу:
add.ts file
В представлении нам нужно создать ссылки для навигации между страницами. Компонент атрибута import {Component, View} from 'angular2/angular2';
import { _settings } from '../../settings'
import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';
import {Inject} from 'angular2/di';
import {Router} from 'angular2/router';
import {AchievementsService} from '../../services/achievementsService';
@Component({
selector: ‘add’,
injectables: [FormBuilder]
})
@View({
templateUrl: _settings.buildPath + ‘/components/add/add.html’,
directives:[formDirectives]
})
export class Add {
} Нам нужно присвоить имя компонента атрибуту, и он позаботится о создании ссылки на основе пути, предварительно настроенного для компонента.
<div>Add New Achievement</div>
<br />
<form>
<div class="input-group">
<span>Title</span>
<input type="text" id="title" class="form-control" />
</div>
<div class="input-group">
<span>Type</span>
<input type="text" id="type" class="form-control" />
</div>
<div class="input-group">
<span>From</span>
<input type="text" id="from" class="form-control" />
</div>
<div> </div>
<div class="input-group">
<input type="submit" value="click" class="btn btn-primary" />
<input type="reset" value="Reset" class="btn" >
</div>
</form>
Последним фрагментом HTML-кода, который нам нужен в корневом компоненте, является элемент router-link
Это место, где дочерние компоненты будут загружены при навигации по представлениям.
<ul class="nav navbar-nav">
<li>
<a router-link="home">Home</a>
</li>
<li>
<a router-link="add">Add</a>
</li>
</ul>
Перечисление всех достижений
Теперь давайте изменим домашний компонент, чтобы отобразить список всех достижений в виде закрепленных блоков на стене. Мы будем использовать Bootstrap для стилизации этой страницы. CSS Bootstrap уже загружен в route-outlet
Прежде чем приступить к работе с пользовательским интерфейсом, давайте создадим сервис для отправки запросов Ajax в API Express.js для взаимодействия с данными. У нас есть файл с именем <router-outlet></router-outlet>
Переименуйте его в качестве index.html
dummyService
Добавьте следующий код в этот файл. Этот фрагмент кода настраивает внедрение зависимостей для службы и добавляет метод для получения всех достижений от службы:
achievementsService
Методы класса AchievementsService
Последние являются объектами, которые имеют встроенные возможности для уведомления, когда что-то меняется. import {Component, View} from 'angular2/angular2';
import { Inject} from 'angular2/di';
import {Http} from 'angular2/http';
export class AchievementsService {
constructor( @Inject(Http) private http: Http) {
}
getAllAchievements(): any {
var path = ‘/api/achievements’;
return this.http.get(path);
}
}Http
AchievementsService
Чтобы продолжить работу с проектом, замените код в NgFor
home.ts
import {Component, View, NgFor} from 'angular2/angular2'; import { _settings } from '../../settings' import {AchievementsService} from '../../services/achievementsService'; import {Inject} from 'angular2/di'; @Component({ selector: 'home', injectables: [AchievementsService] }) @View({ templateUrl: _settings.buildPath + "/components/home/home.html", directives: [NgFor] }) export class Home { achievements: Array; constructor( @Inject(AchievementsService) private achievementsService: AchievementsService) { achievementsService.getAllAchievements() .map(r => r.json()) .subscribe(a => { this.achievements = a; }); } }
Обратный вызов подписки, добавленный в приведенный выше фрагмент, вызывается после того, как наблюдаемое отправляет уведомление. Зоны понимают, как работают наблюдаемые, и обновляют интерфейс после того, как наблюдаемое установило значение. Разметка в файле home.html
<div class="row">
<div *ng-for="#achievement of achievements" class="thumbnail col-md-3 col-sm-3 col-lg-3">
<span class="glyphicon glyphicon-pushpin"></span>
<div class="caption">
<strong>{{achievement.title}}</strong>
</div>
<p class="text-center">Level: {{achievement.type}}</p>
<p class="text-center">From: {{achievement.from}}</p>
</div>
</div>
Все в приведенном фрагменте выглядит знакомо, за исключением двух специальных символов в элементе div
ng-for
Значение этих символов:
- Символ звездочки перед
ng-for
шаблон - Символ хеша перед достижением переменной записи делает его локальной переменной. Может использоваться внутри шаблона для привязки данных
Давайте сохраним эти изменения и запустим приложение. Вы увидите список достижений в виде ящиков.
Добавление нового достижения
У нас должна быть form
Добавьте следующий метод в AchievementsService
addAnAchievement(newAchievement) {
var path = '/api/achievements';
return this.http.post(path, JSON.stringify(newAchievement));
}
Представление add
- Примите значения в форме и отправьте их на сервер Express
- Как только значение будет успешно введено, перенаправьте пользователя на главный экран
В Angular 2 формы могут создаваться и управляться несколькими способами. Они могут управляться шаблонами, моделями и данными. Обсуждение более подробной информации об этих подходах выходит за рамки этой статьи, но, если вам интересно, в этом проекте мы будем использовать подход, основанный на моделях. Хотя мы не будем использовать проверку в этой статье, вы будете рады узнать, что формы в Angular 2 также поддерживают проверку.
В подходе, основанном на модели, нам нужно создать объект модели, который будет привязан к форме, и декларативно прикрепить его к форме. Поля в форме связаны со свойствами объекта модели. Значение объекта модели передается службе для отправки на сервер.
Следующий шаг, который вам нужно выполнить, это открыть файл add.ts
Add
addAchievementForm: any;
constructor( @Inject(FormBuilder) private formBuilder: FormBuilder,
@Inject(Router) private router: Router,
@Inject(AchievementsService) private achievementsService: AchievementsService) {
this.addAchievementForm = formBuilder.group({
title: [''],
type: [''],
from: ['']
});
}
addAchievement() {
this.achievementsService.addAnAchievement(this.addAchievementForm.value)
.map(r => r.json())
.subscribe(result => {
this.router.parent.navigate('/');
});
}
Свойство addAchievementForm
Свойства этого объекта будут прикреплены к элементам управления внутри формы с помощью директивы ng-control
Метод addAchievement
Возможно, вы заметили, что мы не обрабатываем случаи ошибок HTTP-запросов. Это потому, что эта функция еще не доступна в HTTP API, но, безусловно, она станет лучше в будущем.
Теперь откройте файл app.html
<form (ng-submit)="addAchievement()" [ng-form-model]="addAchievementForm">
В приведенном выше фрагменте скобки вокруг ng-submit
Назначенная ей функция будет вызываться, когда form
Квадратные скобки вокруг директивы ng-form-model
Теперь единственное ожидающее изменение — это присоединение полей объекта модели к элементам управления вводом. Следующий фрагмент показывает измененное текстовое поле ввода для заголовка и соответственно изменяет другие элементы управления:
<input type="text" id="title" ng-control="title" class="form-control" />
В заключение сохраните все изменения и запустите приложение. Вы должны иметь возможность добавлять новые достижения сейчас.
Выводы
Angular 2 охватывает новейшие и лучшие технологии переднего мира. Кроме того, использование TypeScript для написания кода повышает производительность разработчиков. Как мы уже видели, фреймворк полностью переписан и помогает вам делать многие вещи более простым способом. Поскольку фреймворк все еще находится в альфа-версии, я предлагаю вам не использовать его в приложении, которое находится в производстве. Будьте терпеливы и подождите, чтобы увидеть, как команда AngularJS формирует своего ребенка.