Angular - четыре старомодных практики, которые НЕ следует переносить в Angular

Kate

Administrator
Команда форума
До изобретения современных JS-фреймворков большинство веб-сайтов были созданы с использованием статического HTML и классических JS-библиотек, таких как jQuery. Многие практики были сформулированы на основе этого стека, но некоторые из них могут больше не применяться в современных фреймворках. Здесь я обобщил четыре классических метода веб-разработки, которые больше не подходят для Angular.

1. Манипулирование экземплярами
Селектор элементов играет важную роль в классической веб-разработке. Когда мы хотим выполнить действие над элементом, мы используем селектор, чтобы получить соответствующий экземпляр и напрямую управлять экземпляром. Выбор экземпляров и управление ими - распространенный и предпочтительный способ работы на классических веб-сайтах. Тем не менее, прямое управление экземпляром (с такими функциями, как @ViewChild), такое как вызов метода общедоступного компонента, чтение некоторых атрибутов компонента и т. Д., Является менее предпочтительным подходом в Angular. Причина в том, что мы не можем гарантировать реактивность при проведении таких манипуляций. Например:

@Component({
selector: 'custom-button',
...
})
export class CustomButtonComponent {
activated = false; public setActivated(value: boolean) {
this.activated = value;
}
}


Нам нужно запускать setActivated вручную каждый раз, когда мы узнаем об изменении состояния:

@Component(...)
export class TestPageComponent {
activated = false; @ViewChild('customButton1') customButton1: CustomButtonComponent;
@ViewChild('customButton2') customButton2: CustomButtonComponent; onDataLoad() {
this.activated = !!this.data.length;
this.customButton1.setActivated(this.activated);
this.customButton2.setActivated(this.activated);
}

...
}

Здесь мы сами управляем реактивностью. Это опасно, поскольку это означает дефект, если новые коды нарушают цепочку назначений, что очень часто. Состояния не реагируют на изменения автоматически, и это главная проблема. Чтобы избежать этой проблемы, мы можем просто использовать официальную привязку @Input и события @Output.

@Component({
selector: 'custom-button',
...
})
export class CustomButtonComponent {
@Input activated = false;
}

Теперь мы можем гарантировать, что активированная внутри кнопки всегда придерживается родительского состояния.

@Component({
...
template: `
<custom-button [activated]="activated">Button 1</custom-button>
<custom-button [activated]="activated">Button 2</custom-button>
`
})
export class TestPageComponent {
activated = false;

onDataLoad() {
this.activated = !!this.data.length;
}

...
}

Также есть преимущество в том, что потенциально меньше кода и, следовательно, меньше сложность. Хотя прямых манипуляций действительно нельзя избежать для некоторых случаев использования, таких как интеграция сторонних библиотек, мы всегда должны стараться избегать их при разработке собственных компонентов.

2. Изменение HTML
Еще одна распространенная операция, которую мы можем выполнять на классических веб-сайтах, - это изменение HTML с помощью JS во время выполнения, например изменение внутреннего HTML, обновление классов и т. Д. Традиционные веб-страницы используют статический HTML, поэтому возможность динамического изменения HTML с помощью JS имеет важное значение для некоторых продвинутых UX конструкции. Тем не менее, современные интерфейсные фреймворки больше не используют статический простой HTML. В качестве решения Angular используется шаблон HTML. Проще говоря, мы можем рассматривать его как собственный HTML с набором дополнительного синтаксиса и логики, добавляемыми для улучшения функциональных возможностей. В Angular не рекомендуется изменять HTML вручную с помощью JS, поскольку это может быть довольно опасно. Шаблон Angular участвует во многих различных частях ядра Angular. Непосредственное изменение HTML может привести к неожиданным побочным эффектам, если не использовать его с осторожностью. Официальный подход к обработке изменений HTML заключается в работе с механизмом обнаружения изменений Angular с синтаксисом шаблона Angular HTML.

<label>{{ isModification ? 'Modify' : 'Create' }}</label>

После многих лет разработки существующая версия шаблона Angular уже охватывает большинство случаев использования, когда нам нужно изменить HTML. Более того, более декларативно то, что все варианты макета явно кодируются в шаблоне. Другим разработчикам намного проще следовать логике, поскольку они могут понять, что может произойти, просто заглянув в шаблоны. Есть несколько редких UX-дизайнов, которые нам все еще могут понадобиться для непосредственного изменения HTML, например, для позиционирования модального или раскрывающегося компонента. Тем не менее, мы всегда должны стараться использовать шаблон Angular, когда это возможно, ради безопасности и удобства обслуживания.

3. Использование обратных вызовов
Обратный вызов - важная функция для асинхронного программирования. Он широко используется на традиционных веб-страницах, например при отправке HTTP-вызовов. Прежде всего, я хотел бы уточнить, что использование обратных вызовов в Angular совершенно нормально, но в некоторых случаях RxJS (RxJS - это библиотека, которая официально поддерживается Angular для создания асинхронных и основанных на событиях программ с использованием наблюдаемых последовательностей.) может лучше выполнять работу, которая в основном связана с межкомпонентной или сервисной коммуникацией. Причина опять же в реактивности. Обратные вызовы для разных компонентов или служб всегда приводят к нереактивным кодам. Например, предположим, что мы используем обратный вызов для реализации вызова API, у нас будет что-то вроде этого:

@Component(...)
export class TestPageComponent implements OnInit {
data: string[]; ngOnInit() {
this.dataService.getData(result => {
this.data = result;
});
} ...
}

Нам всегда нужна дополнительная логика для обработки присвоения данных из результатов обратного вызова состояниям. Будет намного чище, если мы будем использовать RxJS:

@Component(...)
export class TestPageComponent implements OnInit {
data$: Observable<string[]> = this.dataService.getData(); ...
}

Затем мы можем просто использовать асинхронный канал для доступа к данным:

<div>{{ data$ | async }}</div>

Еще одно преимущество использования RxJS перед обратным вызовом - масштабируемость. RxJS поддерживает множество вариантов использования, которые может быть довольно сложно реализовать с помощью обратного вызова, например, наличие нескольких пользователей на одном источнике:

@Component(...)
export class TestPageAComponent {
data$ = this.dataService.getData(); ...
}@Component(...)
export class TestPageBComponent {
data$ = this.dataService.getData(); ...
}


Есть много других функций RxJS, которые отлично справляются с некоторыми классическими проблемами Angular. Чтобы освоить Angular, мы точно не можем пропустить RxJS.

4. Использование объектов конфигурации
Обертывание нескольких аргументов в объект для настройки - обычная практика в классическом JavaScript. Тем не менее, это антипаттерн для компонента Angular.

export interface Configuration {
enableFilter: boolean;
enableSort: boolean;
...
}@Component({
selector: 'custom-grid',
...
})
export class CustomGridComponent {
@Input() configuration: Configuration; ...
}

В Angular есть две проблемы. Во-первых, это мешает установке значения по умолчанию. Для этого нам просто нужно больше кодов, что также означает дополнительную сложность. Здесь я написал еще одну статью ранее для более подробного объяснения этой проблемы:


Другая проблема заключается в том, что привязка объекта может сделать реализацию метода установки очень сложной.

@Input set configuration(configuration: Configuration) {
...
}

Связанный метод установки отслеживает только ссылку. После привязки объекта изменение его атрибутов не вызовет снова метод установки. Это означает, что нам потребуются дополнительные коды для обработки мутации данных, которая может быть очень сложной. Мы можем избежать этой проблемы, деструктурируя ее и сохранив примитивное значение:

@Input set enableFilter(enabled: boolean) { ... }
@Input set enableSort(enabled: boolean) { ... }

Это не только сэкономит время разработки, но и сохранит сложность кода на низком уровне для лучшей долгосрочной поддержки.


Спасибо за прочтение! Надеюсь, эта статья окажется для вас полезной.

Перевод статьи с сайта: https://lukeliutingchun.medium.com/
 
Сверху