Angular Official Example Project Source Code
Default Project Structure Generated by Angular CLI
Typical Project Structure:
my-angular-app/
├── e2e/ # End-to-end tests
├── node_modules/ # Dependency packages
├── src/ # Source code
│ ├── app/ # Application code
│ │ ├── app.component.* # Root component
│ │ ├── app.module.ts # Root module
│ │ └── ... # Other components/services
│ ├── assets/ # Static assets
│ ├── environments/ # Environment configurations
│ ├── styles.css # Global styles
│ └── index.html # Main HTML file
├── angular.json # Project configuration
├── package.json # Dependency management
└── tsconfig.json # TypeScript configurationKey File Analysis:
angular.json: Defines build configurations, asset paths, style preprocessing, etc.tsconfig.json: TypeScript compiler optionsenvironment.*.ts: Environment-specific configurations (development/production)
Component and Module Organization and Design
Modular Design Example:
src/app/
├── core/ # Core module (singleton services)
│ ├── services/ # Global services
│ └── core.module.ts
├── shared/ # Shared module (reusable components)
│ ├── components/ # Shared components
│ └── shared.module.ts
├── features/ # Feature modules (by functionality)
│ ├── user/ # User management module
│ └── product/ # Product management module
└── app.module.ts # Root moduleModule Design Principles:
- CoreModule: Contains singleton services, imported once in the root module
- SharedModule: Contains reusable components/directives/pipes, importable by multiple modules
- FeatureModule: Divided by functionality, lazily loaded
Routing and Navigation Implementation
Routing Configuration Example:
// app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{
path: 'users',
loadChildren: () => import('./features/user/user.module').then(m => m.UserModule)
},
{ path: '**', component: PageNotFoundComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {}Route Guard Implementation:
// auth.guard.ts
@Injectable()
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
if (this.authService.isLoggedIn()) {
return true;
}
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
return false;
}
}Form Handling Implementation
Reactive Forms Example:
// user-form.component.ts
@Component({
selector: 'app-user-form',
templateUrl: './user-form.component.html'
})
export class UserFormComponent {
userForm = this.fb.group({
name: ['', [Validators.required, Validators.minLength(2)]],
email: ['', [Validators.required, Validators.email]],
age: [0, [Validators.min(18), Validators.max(99)]]
});
constructor(private fb: FormBuilder) {}
onSubmit() {
if (this.userForm.valid) {
console.log('Form submitted:', this.userForm.value);
}
}
}Template-Driven Forms:
<!-- login-form.component.html -->
<form #loginForm="ngForm" (ngSubmit)="onSubmit(loginForm)">
<input name="username" ngModel required>
<input name="password" type="password" ngModel required>
<button type="submit" [disabled]="loginForm.invalid">Login</button>
</form>HTTP Communication Implementation
HTTP Service Encapsulation:
// api.service.ts
@Injectable()
export class ApiService {
constructor(private http: HttpClient) {}
getUsers(): Observable<User[]> {
return this.http.get<User[]>('/api/users').pipe(
catchError(this.handleError)
);
}
private handleError(error: HttpErrorResponse) {
// Error handling logic
return throwError('Something went wrong');
}
}Interceptor Implementation:
// auth.interceptor.ts
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('token');
if (token) {
const cloned = req.clone({
headers: req.headers.set('Authorization', `Bearer ${token}`)
});
return next.handle(cloned);
}
return next.handle(req);
}
}NgRx State Management Project Source Code
Store, Actions, and Reducers Implementation
Action Definition:
// user.actions.ts
export const loadUsers = createAction('[User] Load Users');
export const loadUsersSuccess = createAction(
'[User] Load Users Success',
props<{ users: User[] }>()
);
export const loadUsersFailure = createAction(
'[User] Load Users Failure',
props<{ error: any }>()
);Reducer Implementation:
// user.reducer.ts
export const userReducer = createReducer(
initialState,
on(loadUsers, state => ({ ...state, loading: true })),
on(loadUsersSuccess, (state, { users }) => ({
...state,
users,
loading: false
})),
on(loadUsersFailure, (state, { error }) => ({
...state,
error,
loading: false
}))
);Store Configuration:
// app.module.ts
@NgModule({
imports: [
StoreModule.forRoot({ user: userReducer }),
EffectsModule.forRoot([UserEffects])
]
})
export class AppModule {}Effects Implementation and Async Handling
Effect Implementation:
// user.effects.ts
@Injectable()
export class UserEffects {
loadUsers$ = createEffect(() =>
this.actions$.pipe(
ofType(loadUsers),
switchMap(() =>
this.userService.getUsers().pipe(
map(users => loadUsersSuccess({ users })),
catchError(error => of(loadUsersFailure({ error })))
)
)
)
);
constructor(
private actions$: Actions,
private userService: UserService
) {}
}Async Operation Handling:
switchMap: Cancels previous incomplete requestsmergeMap: Allows concurrent requestsconcatMap: Executes requests sequentiallyexhaustMap: Ignores new requests until the current one completes
Selector Optimization
Basic Selectors:
// user.selectors.ts
export const selectUserState = (state: AppState) => state.user;
export const selectAllUsers = createSelector(
selectUserState,
(state: UserState) => state.users
);
export const selectUserLoading = createSelector(
selectUserState,
(state: UserState) => state.loading
);Advanced Selectors:
// Derived selector
export const selectActiveUsers = createSelector(
selectAllUsers,
(users) => users.filter(user => user.isActive)
);
// Parameterized selector
export const selectUserById = (userId: string) => createSelector(
selectAllUsers,
(users) => users.find(user => user.id === userId)
);Selector Optimization Techniques:
- Memoization: Avoids redundant computations
- Composed Selectors: Reuses existing selectors
- Parameterized Selectors: Dynamically fetches data
State Management Debugging and Testing
Redux DevTools Integration:
// store.module.ts
@NgModule({
imports: [
StoreModule.forRoot(reducers, {
metaReducers,
runtimeChecks: {
strictStateImmutability: true,
strictActionImmutability: true
}
}),
StoreDevtoolsModule.instrument({
maxAge: 25,
logOnly: environment.production
})
]
})
export class AppStoreModule {}Unit Test Example:
// user.reducer.spec.ts
describe('User Reducer', () => {
it('should handle loadUsersSuccess', () => {
const initialState: UserState = { users: [], loading: false };
const action = loadUsersSuccess({ users: [{ id: 1, name: 'Test' }] });
const state = userReducer(initialState, action);
expect(state.users).toEqual([{ id: 1, name: 'Test' }]);
expect(state.loading).toBeFalse();
});
});State Management Performance Optimization
Performance Optimization Strategies:
- OnPush Change Detection: Reduces change detection scope
- TrackBy Function: Optimizes ngFor rendering
- Lazy Loading Modules: Reduces initial bundle size
- Selector Memoization: Avoids redundant computations
State Normalization:
// Normalized state structure
{
users: {
byId: {
'1': { id: 1, name: 'User 1' },
'2': { id: 2, name: 'User 2' }
},
allIds: ['1', '2']
}
}Angular Material Component Library Source Code
Component Design and Implementation
Dialog Component Architecture:
MatDialog
├── MatDialogContainer // Container component
├── MatDialogRef // Reference object
├── MAT_DIALOG_DATA // Injection token
└── dialog-config // Configuration optionsTable Component Implementation Key Points:
- Virtual Scrolling:
cdk-virtual-scroll-viewport - Sorting:
MatSortdirective - Pagination:
MatPaginatorcomponent - Filtering:
MatTableDataSourcefiltering methods
Theme and Style Customization
Theme System Implementation:
// Custom theme
@use '@angular/material' as mat;
$primary: mat.define-palette(mat.$indigo-palette);
$accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
$warn: mat.define-palette(mat.$red-palette);
$theme: mat.define-light-theme((
color: (
primary: $primary,
accent: $accent,
warn: $warn
)
));
@include mat.all-component-themes($theme);Style Override Strategies:
- ::ng-deep: Penetrates component style encapsulation (deprecated)
- ViewEncapsulation.None: Disables style encapsulation
- Global Style File: Overrides in styles.css
Component Accessibility and Internationalization
Accessibility Implementation:
- ARIA Attributes: Automatically adds ARIA roles and attributes
- Keyboard Navigation: Supports keyboard operations
- Focus Management: Ensures correct focus order
Internationalization (i18n) Support:
// Using Angular built-in i18n
@Component({
template: `
<p i18n="@@welcomeMessage">Welcome to our app</p>
`
})
export class AppComponent {}
// Using TranslateService (ngx-translate)
constructor(private translate: TranslateService) {
translate.use('en');
}Component Performance Optimization
Virtual Scrolling Optimization:
<cdk-virtual-scroll-viewport itemSize="50" class="list-container">
<div *cdkVirtualFor="let item of items" class="list-item">
{{ item.name }}
</div>
</cdk-virtual-scroll-viewport>Change Detection Optimization:
- OnPush Strategy: Reduces detection frequency
- Immutable Data: Uses immutable data structures
- TrackBy Function: Optimizes list rendering
Component Testing and Debugging
Component Test Example:
// dialog.component.spec.ts
describe('DialogComponent', () => {
let dialogRef: MatDialogRef<DialogComponent>;
let component: DialogComponent;
let fixture: ComponentFixture<DialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [MatDialogModule],
declarations: [DialogComponent]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});Debugging Techniques:
- Augury Tool: Angular application debugging tool
- NgProbeToken: Custom debugging extensions
- Component Tree Inspection: Using browser developer tools
By deeply analyzing the source code of these classic projects, developers can master Angular best practices and design patterns, applying these advanced techniques and architectural concepts to their own projects.



