Fondamentaux du codage angulaire propre

Jetez un œil à ces conseils pour créer du code propre. Certains d’entre eux sont applicables à l’ensemble du développement, et d’autres sont spécifiques aux développeurs Angular.
Maintenant qu’Angular 19 est disponible, il est temps d’écrire du code plus propre ! Nous devons utiliser à la fois les techniques de codage propre classiques et celles spécifiques à Angular.
1. Utiliser la syntaxe du flux de contrôle
Arrêtez d’utiliser *ngIf
et commencez à utiliser la syntaxe du flux de contrôle.
<div *ngIf="isTrue; else DoThis">
<p>Why did I have to create an extra div?</p>
</div>
<ng-template #DoThis>
<p>BTW, you must use ng-template, didn't you know!?</p>
</ng-template>
@if (isTrue) {
<p>Much better! You can do a @Switch as well!</p>
}
@else if (somethingElse) {
<p>Before you had to nest the ifs! Yuck!</p>
}
@else {
<p>Obviously inspired by Svelte!</p>
}
Cela comprend @defer
, @if
, @else
, @for
et @switch
. Voir Expérience de développement Angular 17 : un guide pratique. Le code est plus propre et la taille du bundle est beaucoup plus petite !
2. Utilisez des jetons d’injection au lieu de services
Les jetons d’injection sont vraiment incroyables. C’est ainsi que tous les cadres devraient fonctionner et éliminer les API de contexte.
export const FIREBASE_AUTH = new InjectionToken<Auth | null>(
'firebase-auth',
{
providedIn: 'root',
factory() {
const platformID = inject(PLATFORM_ID);
if (isPlatformBrowser(platformID)) {
return inject(Auth);
}
return null;
}
}
);
C’est beaucoup plus facile à utiliser qu’une classe avec un service. Les fonctions peuvent également être importées comme des variables normales dans les composants. Espérons que les classes seront éventuellement remplacées par des fonctions, même dans les composants.
const auth = inject(FIREBASE_AUTH);
Voir mon Application Todo analogique avec Firebase exemple.
Utiliser des modèles en ligne
Si vous êtes un utilisateur pro-Angular, vous utilisez la CLI Angular pour générer facilement de nouveaux composants. Pour les petits composants rapides, vous devez toujours utiliser styles en ligne et modèles en ligne pour gagner du temps et avoir tout votre code au même endroit.
npm generate component component_name --inline-template --inline-style
Et vous devriez utiliser la version abrégée :
npm g c component_name -t -s
Cela rend l’édition de vos composants extrêmement simple et offre une meilleure lisibilité.
import { Component } from '@angular/core';
@Component({
selector: 'app-temp',
standalone: true,
imports: [],
template: `
<header>
<h1>Some Component!</h1>
<div>Some stuff about some other stuff.</div>
</header>
`,
styles: ``,
})
export class TempComponent {}
Ces jours styles
peut même ne pas être nécessaire si vous utilisez Tailwind.
📝 Je n’ai pas mentionné standalone
composants, qui est désormais l’option par défaut. Cependant, j’espère que vous les utilisez déjà !
Désinscription de ZoneJS
Vous pouvez désormais supprimer ZoneJS de votre application en économisant 13 Ko d’espace !
bootstrapApplication(App, {
providers: [
provideExperimentalZonelessChangeDetection()
]
});
L’avenir d’Angular est sans zone ! Si vous utilisez correctement les signaux, l’ensemble de votre processus de détection de changement angulaire sera plus propre !
📝 Vous devez également supprimer le Polyfills Zone.js!
Supprimez les RxJS inutiles pour les signaux
RxJS n’est pas encore facultatif, mais il le sera éventuellement. Vous ne devez pas utiliser RxJS dans Angular, sauf si vous devez gérer des événements asynchrones avec des conditions de concurrence ou coordonner un flux de données complexe. Voir Pourquoi l’équipe Angular n’a-t-elle pas simplement utilisé RxJS au lieu de Signals ?
// No more need for Behavior Subjects
private _user = new BehaviorSubject<UserType>({
loading: true,
data: null
});
user = this._user.asObservable();
// Just use Signals
const user = signal<{
loading: boolean,
data: userData | null
}>({
loading: true,
data: null
});
Utiliser des résolveurs avec le rendu côté serveur
Les passionnés d’Angular adorent récupérer des données dans un composant. Cela avait du sens avec RxJS, en actualisant les paramètres des composants, et maintenant avec Signals. Si vous récupérez des données, vous souhaiterez peut-être gérer les conditions de concurrence avec les contrôleurs d’abandon, basculer l’état de chargement et afficher les erreurs. Cependant, si vous chargez des données qui doivent être résolues sur le serveur, vous devez utiliser des résolveurs. Le traitement des résultats de récupération sur le serveur est plus rapide, mais plus important encore, vous avez probablement besoin des données récupérées à des fins de référencement dans vos balises méta et votre schéma.
// todos.resolver.ts
import { inject } from '@angular/core';
import { toSignal } from '@angular/core/rxjs-interop';
import { ActivatedRoute, ResolveFn } from '@angular/router';
import { map } from 'rxjs';
export const todosResolver: ResolveFn<Promise<any>> = async (route, state) => {
const todoId = route.paramMap.get('id');
if (!todoId) {
throw new Error('Todo ID is missing in the route!');
}
// Fetch the todo from the API
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId}`);
if (!response.ok) {
throw new Error('Failed to fetch the todo');
}
const todo = await response.json();
return todo;
};
export const injectResolver = <T>(name: string) =>
inject(ActivatedRoute).data.pipe<T>(map(r => r[name]));
export const injectResolverSignal = <T>(name: string) =>
toSignal<T>(injectResolver(name));
// app.routes.ts
export const routes: Routes = [
{ path: 'todos/:id', component: TodosComponent, resolve: { data: todosResolver } },
...
];
Voici un résolveur pour récupérer todos
. Ils peuvent être facilement utilisés dans votre composant.
todo = injectResolverSignal<Todo>('data');
Le signal s’actualisera lorsque l’itinéraire de la page sera actualisé.
Utiliser les principes de codage propre standard
Bien qu’il existe de nombreux principes de conception dans SOLIDEle changement de popularité vers la programmation fonctionnelle en a permis de se démarquer. Ces principes s’appliquent à tous les frameworks JavaScript.
Principe de responsabilité unique
Le principe de responsabilité unique (SRP) stipule que «[t]il ne devrait jamais y avoir plus d’une raison pour qu’une classe change. En d’autres termes, chaque classe ne devrait avoir qu’une seule responsabilité.
Alors que SOLID parlait initialement de programmation orientée objet (POO), la programmation fonctionnelle en JavaScript partage des fonctionnalités communes.
export const LOGIN = new InjectionToken(
'LOGIN',
{
providedIn: 'root',
factory() {
const auth = inject(FIREBASE_AUTH);
return () => {
if (auth) {
signInWithPopup(
auth,
new GoogleAuthProvider()
);
return;
}
throw "Can't run Auth on Server";
};
}
}
);
Ce jeton d’injection a un seul objectif : connecter un utilisateur avec Firebase.
BAISER
« Keep it Simple, Stupid » fonctionne en dehors de la programmation, mais est également important lors de l’écriture de composants.
- Créez des processus simples qui peuvent être facilement compris et réutilisables.
- N’utilisez pas de modèle d’IA pour quelque chose
if
la déclaration peut faire.
Un bon exemple serait l’optimisation pour l’avenir. Si vous avez de nombreux utilisateurs, vous aurez de l’argent pour optimiser plus tard.
SEC
Ne vous répétez pas.
- Utilisez des fonctions réutilisables pour les petits objets au lieu de réinventer la roue.
- Utilisez des composants enfants répétables au lieu de réécrire les mêmes balises d’en-tête dans une boucle.
- Conservez une responsabilité unique pour les fonctions réutilisables et restez simple.
📝 Je dirais également qu’il est acceptable de séparer une fonction utilisée une seule fois. Les fonctions longues sont tout aussi difficiles à suivre.
YAGNI
Vous n’en aurez pas besoin !
- Ne développez pas de fonctionnalités tant qu’elles ne sont pas nécessaires !
- Ne sur-optimisez pas !
- Restez simple !
👓 Comme vous pouvez le constater, tous ces principes fondamentaux de codage se chevauchent.
Utiliser des clauses de garde
Réfracteur votre if
instructions à renvoyer plus tôt au lieu d’utiliser des instructions complexes if / else
déclarations. Cela a rendu mon codage extrêmement simple !
// Before
function processUserInput(input: string | null): string {
if (input !== null) {
if (input.trim() !== "") {
if (input.length > 5) {
return `Valid input: ${input}`;
} else {
return "Input is too short";
}
} else {
return "Input is empty";
}
} else {
return "Input is null";
}
}
// After
function processUserInput(input: string | null): string {
if (input === null) return "Input is null";
if (input.trim() === "") return "Input is empty";
if (input.length <= 5) return "Input is too short";
return `Valid input: ${input}`;
}
⁉️ Lequel est le plus facile à lire ?
Utilisez une meilleure dénomination et moins de commentaires
Les commentaires ont leur place, mais ils ne sont pas nécessaires si vous nommez mieux vos variables.
function calculateTotalPrice(cartItems: CartItem[]): number {
let totalPrice: number = 0;
for (const cartItem of cartItems) {
totalPrice += cartItem.price * cartItem.quantity;
}
return totalPrice;
}
Cette fonction est facile à comprendre car les variables sont clairement nommées. Ne pas utiliser x
ou i
par exemple, lorsqu’il n’est pas clair ce que fait une fonction.
Alors qu’Angular continue d’évoluer au fil du temps, écrire du code plus propre deviendra plus facile. Cependant, les principes de codage propre ne mourront jamais.
Source link