Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Sweet Angular, good forms never felt so good
Search
Ciro Nunes
August 02, 2017
Technology
330
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Sweet Angular, good forms never felt so good
Ciro Nunes
August 02, 2017
More Decks by Ciro Nunes
See All by Ciro Nunes
Rust Front-end with Yew
cironunes
0
110
Type safe CSS with Reason
cironunes
0
160
What I've learned building automated docs for Ansarada's design system
cironunes
0
110
Beyond ng new
cironunes
2
260
Animate your Angular apps
cironunes
0
470
Sweet Angular, good forms never felt so good
cironunes
0
120
Progressive Angular apps
cironunes
3
960
Angular: Um framework. Mobile & desktop.
cironunes
1
620
Firebase & Angular
cironunes
0
310
Other Decks in Technology
See All in Technology
AWSDirectConnectの構築の進め方を整理してみた
masa_my
1
200
BacklogのRAG 今ならこう作る - S3 Vectorsと自前パイプラインの勘所
revsystem
0
140
freeeにおける AI を用いた ブラウザ動作確認の自動化の取り組み
freee
PRO
0
220
"計画的無茶振り"を通してAIネイティブ世代の新人を育てる
subroh0508
1
110
Claude Code on Bedrock で統制をかける小ネタ集/claude-code-bedrock-governance-tips
emiki
1
13k
データマネジメント × 法務で作りあげる、 freeeの新しいデータガバナンスへの軌跡
freee
PRO
1
440
演劇と私とスクラム
chinmo
0
160
Vue.jsのGitHubから学ぶ意思決定
yut0naga1_fa
1
290
契約で守るコンパウンドプロダクトのデザインシステム
yug1224
1
1.5k
Vue で書く 空間コンピューティング、TresJS と WebXR を使ったXR デバイスのフロントエンド開発
hiranuma
0
110
Codex を使った障害対応机上演習の実際
orgachem
PRO
0
360
Draft AIエージェントの トークン消費を最小化する 8つの原則
kinopeee
5
1.8k
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Designing for Timeless Needs
cassininazir
1
530
Building AI with AI
inesmontani
PRO
1
1.3k
What the history of the web can teach us about the future of AI
inesmontani
PRO
2
750
The browser strikes back
jonoalderson
0
1.9k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
The agentic SEO stack - context over prompts
schlessera
0
980
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.2k
Un-Boring Meetings
codingconduct
0
460
What does AI have to do with Human Rights?
axbom
PRO
1
2.5k
Transcript
Sweet Angular good forms, never felt so good
@cironunesdev
None
None
Fill
Fill React
Fill React Validate
Fill React Validate Submit
None
Template-driven
Template-driven Model-driven (reactive)
Template-driven
None
FormsModule
[(ngModel)] FormsModule
[(ngModel)] #tpl reference variables FormsModule
import { NgModule } from '@angular/core'; import { BrowserModule }
from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; @NgModule({ imports: [ BrowserModule, FormsModule ] }) export class AppModule {}
None
model = { name: '' };
<form #heroForm="ngForm"> <input type="text" [(ngModel)]="model.name" name="name"> {{ model.name }} </form>
model = { name: '' };
<form #heroForm="ngForm"> <input type="text" [(ngModel)]="model.name" name="name" #name="ngModel"> <div [hidden]="name.valid ||
name.pristine">Invalid! </div> </form>
Model-driven (reactive)
None
ReactiveFormsModule
FormGroup, FormControl, FormArray, FormBuilder ReactiveFormsModule
import { NgModule } from '@angular/core'; import { BrowserModule }
from '@angular/platform-browser'; import { ReactiveFormsModule } from '@angular/forms'; @NgModule({ imports: [ BrowserModule, ReactiveFormsModule ] }) export class AppModule {}
constructor(private fb: FormBuilder) { this.heroForm = fb.group({ name: ['', [Validators.required,
Validators.minLength(3)]], rival: [], superpowers: fb.group({ invisibility: false, fly: false, nightVision: false, healing: false }, { validator: superpowersValidator }), sex: [], skills: fb.group({ programming: 0, bjj: 0, fifa: 0 }), github: [] }); }
<div class="form-group form-group --big"> <input placeholder="Name *" formControlName="name"> <div *ngIf="heroForm.get('name').touched
&& heroForm.get('name').hasError('required')" > Name is <strong>required </strong> </div> <div *ngIf="heroForm.get('name').touched && heroForm.get('name').hasError('minlength')" > The min length for the name is <strong>3 </strong> </div> </div>
constructor(private fb: FormBuilder) { this.heroForm = fb.group({ name: ['', [Validators.required,
Validators.minLength(3)]], rival: [], superpowers: fb.group({ invisibility: false, fly: false, nightVision: false, healing: false }, { validator: superpowersValidator }), sex: [], skills: fb.group({ programming: 0, bjj: 0, fifa: 0 }), github: [] }); }
export const superpowersValidator = (control: AbstractControl) => { const invisibility
= control.get('invisibility'); const fly = control.get('fly'); const healing = control.get('healing'); const nightVision = control.get('nightVision'); const fields = [invisibility, fly, healing, nightVision] .filter(field => field.value === true); if (fields.length < 2) { return { atleasttwo: true }; } return null; };
Not covered
Not covered Custom controls
Not covered Custom controls Async validators
Not covered Custom controls Async validators Dynamic forms
T akeaways
T akeaways Both styles can be used in the same
app
T akeaways Both styles can be used in the same
app Pick up the one that works the best for each situation
T akeaways Both styles can be used in the same
app Pick up the one that works the best for each situation Embrace Observables
github.com/cironunes/good-forms
Thanks! @cironunesdev