C
Components
Type-safe Angular components with proper Input/Output decorators and lifecycle hooks.
Code
typescript
1// user-card.component.ts2import {3 Component,4 Input,5 Output,6 EventEmitter,7 OnInit,8 OnChanges,9 SimpleChanges,10 ChangeDetectionStrategy,11} from "@angular/core";12 13// Interface for component data14interface User {15 id: number;16 name: string;17 email: string;18 avatar?: string;19 role: "admin" | "user" | "guest";20}21 22interface UserAction {23 type: "edit" | "delete" | "view";24 user: User;25}26 27@Component({28 selector: "app-user-card",29 standalone: true,30 changeDetection: ChangeDetectionStrategy.OnPush,31 template: `32 <div class="user-card" [class.admin]="user.role === 'admin'">33 <img [src]="user.avatar || defaultAvatar" [alt]="user.name" />34 <h3>{{ user.name }}</h3>35 <p>{{ user.email }}</p>36 <span class="role-badge">{{ user.role }}</span>37 38 <div class="actions">39 <button (click)="onAction('view')">View</button>40 <button (click)="onAction('edit')" *ngIf="editable">Edit</button>41 <button (click)="onAction('delete')" *ngIf="deletable">Delete</button>42 </div>43 </div>44 `,45 styles: [`46 .user-card { padding: 1rem; border: 1px solid #ddd; border-radius: 8px; }47 .admin { border-color: #3b82f6; }48 .role-badge { padding: 2px 8px; border-radius: 4px; background: #e5e7eb; }49 `],50})51export class UserCardComponent implements OnInit, OnChanges {52 // Input properties with default values53 @Input({ required: true }) user!: User;54 @Input() editable = false;55 @Input() deletable = false;56 @Input() defaultAvatar = "/assets/default-avatar.png";57 58 // Output events59 @Output() action = new EventEmitter<UserAction>();60 @Output() userChange = new EventEmitter<User>();61 62 ngOnInit(): void {63 console.log("UserCard initialized for:", this.user.name);64 }65 66 ngOnChanges(changes: SimpleChanges): void {67 if (changes["user"]) {68 console.log(69 "User changed from",70 changes["user"].previousValue,71 "to",72 changes["user"].currentValue73 );74 }75 }76 77 onAction(type: UserAction["type"]): void {78 this.action.emit({ type, user: this.user });79 }80}81 82// user-list.component.ts - Parent component83@Component({84 selector: "app-user-list",85 standalone: true,86 imports: [UserCardComponent],87 template: `88 <div class="user-list">89 <h2>Users ({{ users.length }})</h2>90 @for (user of users; track user.id) {91 <app-user-card92 [user]="user"93 [editable]="canEdit"94 [deletable]="canDelete"95 (action)="handleAction($event)"96 />97 }98 </div>99 `,100})101export class UserListComponent {102 users: User[] = [103 { id: 1, name: "Alice", email: "alice@example.com", role: "admin" },104 { id: 2, name: "Bob", email: "bob@example.com", role: "user" },105 ];106 107 canEdit = true;108 canDelete = false;109 110 handleAction(event: UserAction): void {111 console.log(`Action: ${event.type} on user: ${event.user.name}`);112 113 switch (event.type) {114 case "view":115 // Navigate to user detail116 break;117 case "edit":118 // Open edit modal119 break;120 case "delete":121 this.users = this.users.filter((u) => u.id !== event.user.id);122 break;123 }124 }125}Run this example locally
$ ng new my-app --strict