If/Else больше нет: лучшие практики для разработчиков Angular
1 ноября 2023 г.Angular – это популярный интерфейсный фреймворк, получивший широкое признание благодаря своим надежным функциям и простоте использования. Однако, как и любой другой язык или среда программирования, он имеет свой набор проблем, одна из которых связана со сложной условной логикой. в вашем коде. В этой статье мы рассмотрим концепцию отказа от структур if/else в коде Angular и предоставим практические советы и примеры, которые помогут вам писать более чистый и удобный в сопровождении код.
Проблема со структурами if/else
Структуры if/else или условные операторы являются фундаментальной частью программирования. Они позволяют разработчикам принимать решения в своем коде на основе определенных условий. Хотя они необходимы, их широкое использование может привести к нескольким проблемам:
- Сложность. По мере роста вашей кодовой базы количество операторов if/else может резко увеличиваться, что затрудняет чтение и понимание вашего кода. Эта сложность может привести к ошибкам и проблемам с обслуживанием.
- Читаемость. Чрезмерное использование операторов if/else может ухудшить читабельность вашего кода, затрудняя быстрое понимание логики другими разработчиками (и даже вами в будущем).
- Удобство сопровождения. Код со слишком большим количеством структур if/else может оказаться сложным в обслуживании, поскольку любые изменения или обновления могут потребовать внесения изменений в нескольких местах.
- Сложность тестирования. Тестирование кода с многочисленными ветвями if/else может оказаться громоздким и привести к неполному покрытию тестами. ол>
Чтобы решить эти проблемы, важно принять более структурированный и специфичный для Angular подход к обработке условной логики в ваших приложениях.
Как избежать if/else в Angular: директива ngSwitch
Angular предоставляет удобное решение для обработки условной логики в шаблонах с помощью директивы ngSwitch
. Он позволяет переключаться между несколькими представлениями в зависимости от условия, тем самым устраняя необходимость в обширных структурах if/else. Давайте углубимся в пример, чтобы увидеть, как это работает:
Пример: использование ngSwitch
Предположим, у вас есть простой компонент Angular, который отображает сообщение в зависимости от дня недели. Вместо использования операторов if/else вы можете использовать директиву ngSwitch
следующим образом:
import { Component } from '@angular/core';
@Component({
selector: 'app-day-message',
template: `
<div [ngSwitch]="dayOfWeek">
<p *ngSwitchCase="'Monday'">It's the start of the week.</p>
<p *ngSwitchCase="'Friday'">It's almost the weekend!</p>
<p *ngSwitchDefault>Enjoy your day!</p>
</div>
`,
})
export class DayMessageComponent {
dayOfWeek = 'Monday';
}
В этом примере мы используем директиву ngSwitch
для переключения между различными сообщениями на основе значения свойства dayOfWeek
. Директива *ngSwitchCase
определяет условия, а *ngSwitchDefault
обеспечивает запасной вариант для всех остальных случаев.
Используя ngSwitch
, мы устранили необходимость в структурах if/else и сделали код более читабельным и удобным в обслуживании.
Использование угловых каналов
Angular Pipes — еще одна мощная функция, которая поможет вам избежать операторов if/else, предоставляя возможность преобразовывать и форматировать данные в шаблонах. Вы можете использовать каналы для условного форматирования данных на основе определенных критериев. Давайте рассмотрим пример:
Пример: использование каналов для условного форматирования
Предположим, у вас есть список продуктов, и вы хотите отображать их по-разному в зависимости от того, есть ли они на складе или нет. Вместо использования операторов if/else вы можете использовать структурные директивы ngIf
и ngElse
вместе с настраиваемым каналом, например:
import { Component } from '@angular/core';
@Component({
selector: 'app-product-list',
template: `
<div *ngFor="let product of products">
<h3>{{ product.name }}</h3>
<p>Price: {{ product.price | currency }}</p>
<p *ngIf="product.inStock; else outOfStock">In Stock</p>
<ng-template #outOfStock>Out of Stock</ng-template>
</div>
`,
})
export class ProductListComponent {
products = [
{ name: 'Product A', price: 49.99, inStock: true },
{ name: 'Product B', price: 29.99, inStock: false },
// ...more products
];
}
В этом примере мы используем директиву ngIf
для условного отображения контента на основе свойства inStock
каждого продукта. Если товар есть на складе, отображается надпись «В наличии»; в противном случае отображается сообщение «Нет в наличии».
Пользовательские директивы
В некоторых случаях вам может потребоваться реализовать собственную логику, выходящую за рамки возможностей встроенных директив Angular. Для этих сценариев вы можете создавать собственные директивы, чтобы инкапсулировать условную логику и поддерживать чистоту шаблонов. Вот пример:
Пример: создание пользовательской директивы
Предположим, вы хотите отобразить специальный значок скидки для товаров, на которые распространяется скидка. Вместо добавления сложной логики if/else в шаблон вы можете создать специальную директиву для обработки такого поведения:
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appDiscountBadge]'
})
export class DiscountBadgeDirective {
@Input() set appDiscountBadge(hasDiscount: boolean) {
if (hasDiscount) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) {}
}
Теперь в вашем шаблоне вы можете использовать пользовательскую директиву следующим образом:
<div *ngFor="let product of products">
<h3>{{ product.name }}</h3>
<p>Price: {{ product.price | currency }}</p>
<div *appDiscountBadge="product.hasDiscount" class="discount-badge">
Special Discount!
</div>
</div>
Такой подход отделяет условную логику от шаблона, что упрощает понимание и поддержку.
Раздел часто задаваемых вопросов
Q1. Почему мне следует избегать структур if/else в моем коде Angular?
А1. Избегание структур if/else в вашем коде Angular приводит к более читабельности, удобству сопровождения и и тестируемый код. Это снижает сложность и повышает общее качество кода.
В2. Когда мне следует использовать собственные директивы вместо встроенных функций Angular, таких как ngIf и ngSwitch?
А2. Вам следует рассмотреть возможность использования пользовательских директив, когда у вас есть определенное, многократно используемое условное поведение, выходящее за рамки того, что предлагают встроенные директивы. Пользовательские директивы обеспечивают понятный и организованный способ инкапсуляции такой логики.
Q3. Есть ли влияние на производительность, которое следует учитывать при использовании ngIf или пользовательских директив для условного рендеринга?
А3. Механизм обнаружения изменений Angular эффективен и оптимизирует рендеринг. Однако для обеспечения оптимальной производительности важно учитывать количество условных операторов и их сложность.
Заключение
Избегание структур if/else в коде Angular — лучшая практика, которая приводит к созданию более удобного в обслуживании и читаемости кода. Используя встроенные функции Angular, такие как директива ngSwitch, каналы и пользовательские директивы, вы можете сделать свой код более чистым и организованным. Помните, что цель состоит не в том, чтобы просто исключить if/else.
Оригинал