Angular 2: Всех переиграл
Евгений Жарков
DOOR3
eu.zharkov@gmail.com
@2j2e
Текущий статус
Alpha
Общий вид
@Template({
url: 'foo.html'
})
@Component({
selector: 'foo',
})
class Foo {
bar: string;
constructor() {
this.bar = 'baz';
this.bar = 2; // compiler throws an error
}
}
ToDo пример
@Template({
url: 'todos.html'
})
@Component({
selector: 'todo-app',
})
class TodoApp {
constructor() {
this.todos = ['Item1', 'Item2'];
}
}
Компоненты
@Template({
url: 'todos.html'
})
@Component({
selector: 'todo-app',
})
<todo-­‐app></todo-­‐app>
bootstrap
@Component({
selector: 'todo-app',
})
@Template({ url: 'todos.html' })
export class TodoApp {
todos;
constructor() {
this.todos = ['Item1', 'Item2'];
}
}
import {bootstrap} from 'angular';
import {TodoApp} from 'todoapp';
bootstrap(TodoApp);
План построения приложения
1.Создать модуль
2.Объявить ng-app
3.Создать контроллер
4.Закинуть данные в $scope
5.Объявить контроллер
6.Создать шаблон
1.Создать компонент
2.Создать шаблон
3.Bootstrap
4.Транспиляция
Angular 1.X Angular 2
Шаблоны
@Template({
url: 'name-change.html'
})
@Component({
selector: 'name-change',
})
class NameChange {
constructor() {
this.name = '';
}
changeName(newName) {
this.name = newName;
}
}
Шаблоны
<div> My name is {{ name }} </div>
<div>
<input #newname type="text">
<button (click)="changeName(newname.value)"
[disabled]="newname.value == 'David'">
Change Name
</button>
</div>
Локальные переменные
<div>
<input #newname type="text">
{{ newname.value }}
</div>
Обработчик событий
<div>
<input #newname type="text">
<button (click)="changeName($event, newname.value)">
</div>
Привязка данных
<div>
<input #newname type="text">
<span [textContent]="newname.value"></span>
</div>
]
Привязка данных
]
@Template({
url: 'name-change.html'
})
@Component({
selector: 'name-change',
})
class NameChange {
constructor() {
this.name = '';
}
changeName(newName) {
this.name = newName;
}
}
<div> My name is {{ name }} </div>
<div>
<input #newname type="text">
<button (click)="changeName(newname.value)"
[disabled]="newname.value == 'David'"> Change Name
</button>
</div>
Определение изменений
Формы
Это непросто
•Сложная логика
•Тестирование
•Переодически изменения
Логика
•Зависимости элементов друг от друга
•Пользователь может вводить неверные данные, в разном порядке
•Хаотичное появление ошибок
Тестирование
•Шаблоны должны компилироваться
•Это позволяет создавать множество e2e тестов
•Получаем быстрые и изолированные тесты
Изменения
•Ожидание ответа сервера
•Обработка формы при okeyup или onchange
•Изменения зависимых элементов управлений
Angular 2 Forms
- Отдельный модуль по типу модуля маршрутизации
- Не обязательный, но полезные, должен быть
Формы
- Imperative Driven
- Data Driven
- Template Driven
Формы
•Комплексная логика - обрабатываемая элементами управлениями и
валидаторами
•Тестирование - изолированная от DOM
•Обработка изменений - observable
Элементы управления
]
// create a control
var nameControl = new Control("David");
// store its value
var nameValue = nameControl.value;
// check control states
var isValid = nameControl.valid;
var hasBeenChanged = nameControl.dirty;
var hasNotBeenChanged = nameControl.pristine;
var numErrors = nameControl.errors.length;
Группа элементов управления
]
// create a control group
var group = new ControlGroup({
fullName: new Control("David East", Validators.required),
username: new Control("ng2rox", Validators.required),
favColor: new Control("")
});
Построение форм
]
// create a builder
var builder = new FormBuilder();
// build a group w/ controls
var group = builder.group({
fullName: ["David East", Validators.required],
username: ["ng2rox", Validators.required],
favColor: ["Blue"]
});
Валидаторы
]
import {bootstrap, Component, View} from 'angular2/angular2';
import {FormBuilder, Validators, FormDirectives, ControlGroup} from
'angular2/forms';
@Component({
selector: 'form-app'
})
@View({
url: 'form-app.html',
directives: [FormDirectives]
})
class FormApp {
myForm: ControlGroup;
constructor(builder: FormBuilder) {
this.myForm = builder.group({
fullName: ["", Validators.required],
username: ["", Validators.required],
favColor: [""]
});
}
}
Изолированное тестирование
]
var builder = new FormBuilder();
var app = new AppComponent(builder);
// The AppComponent is initially in an invalid state
// Assertion passes
console.assert(app.myForm.valid === false);
// Assertion fails
console.assert(app.myForm.valid === true);
Шаблоны
]
<div [control-group]="myForm">
<input [control]="myForm.controls.fullName">
</div>
Шаблоны, краткий синтаксис
]
<div [control-group]="myForm">
<!-- myForm.controls.fullName-->
<input control="fullName">
</div>
Вложенные группы
]
// create a builder
var builder = new FormBuilder();
// build a group w/ controls
var group = builder.group({
fullName: ["David East", Validators.required],
username: ["ng2rox", Validators.required],
// nested group
address: builder.group({
street: ["", Validators.required],
streetLine2: [""],
city: ["", Validators.required],
state: ["", Validators.required],
zip: ["", Validators.required]
});
});
var isValid = group.controls.address.valid; // is the address
valid?
Пример
]
<div [control-group]="myForm">
<input control="fullName">
<input control="username">
<!-- Nested Control Group -->
<div control-group="address">
<input control="street">
<input control="streetLine2">
<input control="city">
<input control="state">
<input control="zip">
</div>
</div>
Observables
]
var control = new Control();
var ref = new Firebase('https://
ngforms.firebaseio.com/control')
// Save updates to Firebase
control.valueChanges.subscribe(function(value) {
ref.set(value)
});
Angular-разработчик ждет
окончательного релиза
HAHAHA!
Wait, i don’t
get it.
Вопросы!
Система мотивации
За каждый вопрос - google наклейка
Ссылки
- Angular 2 Forms
- Forms in Angular 2
- Change Detection in Angular 2 (Victor Savkin)
- Angular2 - First Impressions (Minko Gechev)
- An Angular2 Todo App: First look at App Development in Angular2

Angular 2: Всех переиграл