If/Else больше нет: лучшие практики для разработчиков Angular

If/Else больше нет: лучшие практики для разработчиков Angular

1 ноября 2023 г.

Angular – это популярный интерфейсный фреймворк, получивший широкое признание благодаря своим надежным функциям и простоте использования. Однако, как и любой другой язык или среда программирования, он имеет свой набор проблем, одна из которых связана со сложной условной логикой. в вашем коде. В этой статье мы рассмотрим концепцию отказа от структур if/else в коде Angular и предоставим практические советы и примеры, которые помогут вам писать более чистый и удобный в сопровождении код.

Проблема со структурами if/else

Структуры if/else или условные операторы являются фундаментальной частью программирования. Они позволяют разработчикам принимать решения в своем коде на основе определенных условий. Хотя они необходимы, их широкое использование может привести к нескольким проблемам:

  1. Сложность. По мере роста вашей кодовой базы количество операторов if/else может резко увеличиваться, что затрудняет чтение и понимание вашего кода. Эта сложность может привести к ошибкам и проблемам с обслуживанием.
  2. Читаемость. Чрезмерное использование операторов if/else может ухудшить читабельность вашего кода, затрудняя быстрое понимание логики другими разработчиками (и даже вами в будущем).
  3. Удобство сопровождения. Код со слишком большим количеством структур if/else может оказаться сложным в обслуживании, поскольку любые изменения или обновления могут потребовать внесения изменений в нескольких местах.
  4. Сложность тестирования. Тестирование кода с многочисленными ветвями if/else может оказаться громоздким и привести к неполному покрытию тестами.
  5. Чтобы решить эти проблемы, важно принять более структурированный и специфичный для 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.


    Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE