Angular Fundamentals Slides
Angular Fundamentals Slides
● Angular CLI
Programming logic in your This is how you define your Styling your templates
application markup in templates
How do you build components in
Angular?
app.component.ts
@Component({
})
@Component({
selector: 'app-root',
})
@Component({
selector: 'app-root',
standalone: true,
})
@Component({
selector: 'app-root',
standalone: true,
template: `<h1>Hey, Frontend Masters!</h1>`,
})
@Component({
selector: 'app-root',
standalone: true,
template: `<h1>Hey, Frontend Masters!</h1>`,
styles: `h1 { color: red }`,
})
@Component({
selector: 'app-root',
standalone: true,
template: `<p> Hey, Frontend Masters!</p>`,
styles: `h1 { color: red }`,
})
class AppComponent {}
<section>
<p> Welcome back, USER</p>
</section>
<section>
<p> Welcome back, USER</p>
</section>
@Component ({ ... })
export class WelcomeComponent {
userName = 'codingChamp';
}
<section>
<p> Welcome back, USER</p>
</section>
<section>
<p> Welcome back, {{ ?? }}</p>
</section>
interpolation
<section>
<p> Welcome back, {{userName}}</p>
</section>
@Component({
selector: 'app-dashboard',
template: `
<section>
<p>Welcome back</p>
</section>
`,
})
export class DashboardComponent {}
@Component({
selector: 'app-dashboard',
template: `
<section>
<p>Welcome back</p>
</section>
`,
imports: [UserInfoComponent]
})
export class DashboardComponent {}
@Component({
selector: 'app-dashboard',
template: `
<section>
<p>Welcome back</p>
<app-user-info />
</section>
`,
imports: [UserInfoComponent]
})
export class DashboardComponent {}
<section>
<!-- user.isLoggedIn -->
<p>Please login</p>
<!-- !user.isLoggedIn -->
<p>Welcome back</p>
</section>
<section>
@if( expr ) {
<p>Please login</p>
}
<p>Welcome back</p>
</section>
<section>
@if(user.isLoggedIn) {
<p>Please login</p>
}
<p>Welcome back</p>
</section>
<section>
@if(user.isLoggedIn) {
<p>Please login</p>
} @else {
<p>Welcome back</p>
}
</section>
Editor Preview Both
home.component.html
<section>
@if(orderAmount < 50 ) {
<p>Your discount amount is 0</p>
} @else if (orderAmount < 100 ) {
<p> Your discount amount is {{ orderAmount * .1 }}</p>
} @else {
<p>Your discount amount is {{ orderAmount * .2}}</p>
}
</section>
<article>
@for(item of cart; track item.id) {
<p>{{item.price}}</p>
}
</article>
<article>
@for(item of cart; track item.id) {
<p>{{item.price}}</p>
} @empty {
<p>Your cart is empty</p>
}
</article>
@Component() {
template: `
<button type="button" [disabled]="isDisabled">
Submit
</button>
`
}
export class AppComponent {
isDisabled = false;
}
@Component() {
template: `
...
<button type="button">Save Progress</button>
`
}
export class AppComponent {}
@Component() {
template: `
<button type="button" (click)="handleClick()">
Save Progress
</button>
`
}
export class AppComponent {
handleClick() { … }
}
@Component({
selector: 'app-cmp',
template: `<app-user-card />`,
imports: [UserCardComponent],
})
export class AppComponent {
user: User = { name: 'Ashley', bio: 'Cool developer',};
}
@Component({
selector: 'app-cmp',
template: `<app-user-card [userData]="user"/>`,
imports: [UserCardComponent],
})
export class AppComponent {
user: User = { name: 'Ashley', bio: 'Cool developer',};
}
@Component({
selector: 'app-user-card',
template: `
<section>
<p>{{userData.name}}</p><p>{{userData.bio}}</p>
</section>`,
})
export class AppComponent {
@Input() userData: User = {...}; // default user data
}
@Component({
template: `
<button class="btn" (click)="addItem()">Add Item</button>
`,
})
export class ProductListComponent {
@Output() addItemEvent = new EventEmitter<string>();
...
}
@Component({
template: `
<button class="btn" (click)="addItem()">Add Item</button>
`,
})
export class ProductListComponent {
@Output() addItemEvent = new EventEmitter<string>();
addItem() { this.addItemEvent.emit('🐢'); }
}
@Component({
template: `
<app-child (addItemEvent)="addItem($event)" />
`,
imports: [ChildComponent],
})
export class AppComponent {
items: string[] = [];
addItem(item: string) { this.items.push(item); }
}
@angular/router
routes.ts
@Component({
selector: 'app-root',
standalone: true,
template: `
<router-outlet />
`,
styles: '',
imports: [RouterModule]
})
export class AppComponent {}
routerLink
app.component.ts
@Component({
template: `
<a routerLink="/details">Details</a>
<router-outlet />
`,
standalone: true,
imports: [RouterOutlet, RouterLink],
})
export class AppComponent {}
/details/1
routes.ts
@Component({...})
export class DetailsComponent {
productId = -1;//dest for route info
@Input()
set id(value: number) {
this.productId = value;
}
}
Forms
A tale of two systems
<form name="loginForm">
<label>Username:
<input type="text" />
</label>
<label for="password">Password:
<input type="password" />
</label>
<button type="submit">Login</button>
</form>
<form name="loginForm">
<label>Username:
<input type="text" [(ngModel)]="username"/>
</label>
<label for="password">Password:
Banana in a box
<input type="password" /> Property binding
+
</label> Event
<button type="submit">Login</button>
</form>
<form name="loginForm">
<label>Username:
<input type="text" />
</label>
<label for="password">Password:
<input type="password" [(ngModel)]="password"/>
</label>
<button type="submit">Login</button>
</form>
@Component({
imports: [FormsModule],
templateUrl: 'app.component.html',
})
export class AppComponent {
username = "";
password = "";
}
@Component({
imports: [ReactiveFormsModule],
templateUrl: 'app.component.html',
})
export class AppComponent {
loginForm = new FormGroup({
name: new FormControl(''),
email: new FormControl(''),
});
}
<form name="loginForm">
<label>Username:
<input type="text" />
</label>
<label for="password">Password:
<input type="password" />
</label>
<button type="submit">Login</button>
</form>
<label for="password">Password:
<input type="password" />
</label>
<button type="submit">Login</button>
</form>
<label for="password">Password:
<input type="password" />
</label>
<button type="submit">Login</button>
</form>
<label for="password">Password:
<input type="password" formControlName="password"/>
</label>
<button type="submit">Login</button>
</form>
<label for="password">Password:
<input type="password" formControlName="password"/>
</label>
<button type="submit">Login</button>
</form>
@Component({...})
export class AppComponent {
loginForm = new FormGroup(...);
handleSubmit() {
this.loginWithCredentials(this.loginForm.value);
}
}
})
export class CarService {...}
@Component({...})
export class AppComponent {
carService = inject(CarService);
}
@Component({...})
export class AppComponent {
carService = inject(CarService);
cars: string[]
constructor() {
this.carService.getCars();
}
}
@Component({
template: `<p>{{ lastName() }}, {{ firstName() }}</p>`
})
export class AppComponent {
firstName = signal('Jessica');
lastName = signal('Wesley');
}
signal
signal
app.component.ts //Defining computed signals
@Component({
template: `<p>{{ fullName() }}</p>`
})
export class AppComponent {
firstName = signal('Simona');
lastName = signal('Cotin');
fullName = computed(() => `${firstName()} ${lastName()}`);
}
computed
app.component.ts //Defining effect signals
@Component({
template: `<p>{{ fullName() }}</p>`
})
export class AppComponent {
firstName = signal('Simona');
lastName = signal('Cotin');
effect(() => console.log('Updated: ' + lastName()));
}
● on idle
● on immediate
● on timer(...)
● on viewport(...)
● on interaction(...)
● on hover(...)
Deferrable Views + Prefetching
app.component.html // Deferrable views w/prefetching