Анимация фигур в виде вирусов на Three.js.
👉 @sWebDev
Frontender Libs - это Telegram канал, который специализируется на обзоре библиотек для разработки веб-интерфейсов на языках программирования JavaScript и CSS. Если вы занимаетесь фронтенд-разработкой и постоянно ищете новые инструменты для улучшения своего кода и повышения производительности, то этот канал идеально подойдет для вас. Здесь вы найдете обзоры самых популярных и актуальных библиотек, а также сможете узнать о последних трендах и новинках в мире веб-разработки. Канал поддерживается опытными специалистами, которые имеют большой опыт работы в данной области. Не упустите возможность быть в курсе всех новостей и тенденций в фронтенд-разработке - подписывайтесь на Frontender Libs прямо сейчас! Для сотрудничества, рекламы или покупки рекламы вы можете связаться с администраторами канала по указанным контактам.
20 Feb, 07:12
19 Feb, 06:52
18 Feb, 14:33
17 Feb, 15:04
17 Feb, 08:07
16 Feb, 09:15
15 Feb, 14:15
retryWhen
?15 Feb, 08:06
14 Feb, 08:33
13 Feb, 15:10
13 Feb, 09:00
13 Feb, 07:00
12 Feb, 08:31
11 Feb, 15:00
.window.top {
position: absolute;
transform: rotate(120deg);
overflow: hidden;
}
11 Feb, 08:12
10 Feb, 12:00
10 Feb, 07:43
ChangeDetectorRef.detach()
позволяет отключить компонент от системы обнаружения изменений. Это полезно, если компонент не должен отслеживать изменения постоянно. После вызова detach()
Angular перестанет проверять компонент и его потомков на изменения, пока вы не вызовете обновление вручную через detectChanges()
.import { ChangeDetectorRef, Component } from '@angular/core';
@Component({
selector: 'app-performance',
template: `<div>{{ counter }}</div>`
})
export class PerformanceComponent {
counter = 0;
constructor(private cdr: ChangeDetectorRef) {}
ngOnInit() {
this.cdr.detach(); // Отключаем отслеживание изменений
setInterval(() => {
this.counter++; // Обновляем данные
this.cdr.detectChanges(); // Вручную запускаем проверку изменений
}, 1000);
}
}
ChangeDetectorRef.detach()
отключает систему обнаружения изменений, а вызов detectChanges()
вручную обновляет интерфейс. 09 Feb, 09:13
08 Feb, 15:14
ApplicationRef.tick()
?08 Feb, 07:12
07 Feb, 08:02
06 Feb, 17:10
06 Feb, 15:10
06 Feb, 07:12
05 Feb, 06:52
04 Feb, 14:33
03 Feb, 17:30
03 Feb, 11:31
03 Feb, 08:11
runInInjectionContext()
.import { inject, runInInjectionContext, Injectable, EnvironmentInjector } from '@angular/core';
@Injectable({ providedIn: 'root' })
class MyService {
logMessage() {
console.log('Hello from MyService!');
}
}
function executeWithDI(injector: EnvironmentInjector) {
runInInjectionContext(injector, () => {
const myService = inject(MyService);
myService.logMessage();
});
}
runInInjectionContext()
для создания контекста инъекции. Внутри этого контекста вызывается функция inject()
для получения экземпляра MyService, после чего вызывается метод logMessage()
. 02 Feb, 09:15
01 Feb, 14:15
AnimationTrigger
в Angular?01 Feb, 08:06
31 Jan, 08:33
30 Jan, 15:10
30 Jan, 07:35
29 Jan, 14:00
29 Jan, 08:31
28 Jan, 15:21
28 Jan, 08:12
27 Jan, 07:43
typescriptimport { Injectable, ErrorHandler } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { retryWhen, delay, scan } from 'rxjs/operators';
@Injectable()
export class CustomErrorHandler implements ErrorHandler {
constructor(private http: HttpClient) {}
retryRequest(url: string) {
this.http.get(url).pipe(
retryWhen(errors =>
errors.pipe(
scan((attempts) => {
if (attempts >= 5) throw errors;
return attempts + 1;
}, 0),
delay(attempts => Math.pow(2, attempts) * 1000) // Экспоненциальная задержка
)
)
).subscribe(data => console.log('Success:', data));
}
}
26 Jan, 09:13
25 Jan, 15:14
@SkipSelf()
?25 Jan, 07:12
24 Jan, 09:00
23 Jan, 14:36
23 Jan, 07:12
22 Jan, 06:52
21 Jan, 15:14
21 Jan, 07:29
20 Jan, 08:11
ApplicationRef.tick()
используется для запуска цикла обнаружения изменений вручную. Это полезно, когда изменения происходят вне зоны Angular, например, в callback-функциях или таймерах. typescript
import { ApplicationRef, Component } from '@angular/core';
@Component({
selector: 'app-manual-tick',
template: `<p>{{ message }}</p>`,
})
export class ManualTickComponent {
message = 'Ожидание...';
constructor(private appRef: ApplicationRef) {
setTimeout(() => {
this.message = 'Изменение произошло';
this.appRef.tick(); // Обновляем вручную
}, 3000);
}
}
tick()
изменения в message
не были бы отражены в шаблоне, так как они происходят вне зоны Angular. 11 Jan, 07:12
10 Jan, 08:02
09 Jan, 14:36
<script>
при использовании dangerouslySetInnerHTML, встроенные обработчики событий, такие как onclick, всё же могут выполняться. Автор демонстрирует, как это может привести к потенциальным уязвимостям, и предлагает способы их предотвращения, включая использование функций для очистки HTML-кода от встроенных обработчиков событий перед его вставкой.09 Jan, 07:12
08 Jan, 06:52
07 Jan, 14:33
06 Jan, 14:40
06 Jan, 12:40
06 Jan, 08:11
@SkipSelf()
в Angular заставляет DI пропустить текущий провайдер и искать зависимость в родительском инжекторе. Это полезно, если нужно использовать родительский провайдер вместо локального.@Injectable({ providedIn: 'root' })
export class ConfigService {
constructor(public config: string) {}
}
@Component({
selector: 'app-parent',
providers: [{ provide: ConfigService, useValue: new ConfigService('Parent Config') }],
template: `<app-child></app-child>`,
})
export class ParentComponent {}
@Component({
selector: 'app-child',
providers: [{ provide: ConfigService, useValue: new ConfigService('Child Config') }],
template: `{{ configService.config }}`,
})
export class ChildComponent {
constructor(@SkipSelf() public configService: ConfigService) {}
}
@SkipSelf()
исключает локальный ConfigService
в ChildComponent
, используя родительский провайдер. 05 Jan, 09:15
04 Jan, 14:15
runOutsideAngular()
?04 Jan, 08:06
03 Jan, 08:33
02 Jan, 15:10
resource
и rxResource
, автор демонстрирует создание загрузчиков данных, работу с состояниями (загрузка, ошибка, успех) и обработку запросов с помощью Promise
и Observable
. Пример с CRUD-приложением для продуктов объясняет использование этих подходов в реальных проектах.02 Jan, 07:35
01 Jan, 08:31
31 Dec, 15:21
31 Dec, 08:12
30 Dec, 07:43
Injector.create()
предоставляет возможность вручную создать инжектор и настроить его с необходимыми зависимостями. import { Injector } from '@angular/core';
class LoggerService {
log(message: string) {
console.log('Logger:', message);
}
}
// Создаем локальный инжектор с конфигурацией
const injector = Injector.create({
providers: [
{ provide: LoggerService, useClass: LoggerService }
]
});
// Получаем экземпляр LoggerService из инжектора
const logger = injector.get(LoggerService);
logger.log('Динамическое создание зависимости выполнено!');
LoggerService
в локальном контексте. 29 Dec, 09:13
28 Dec, 15:14
AnimationBuilder
в Angular?28 Dec, 07:12
27 Dec, 08:02
26 Dec, 14:36
useRef
, чтобы сделать интерфейс удобнее и отзывчивее.26 Dec, 07:12
25 Dec, 06:52
24 Dec, 14:33
24 Dec, 07:29
23 Dec, 08:11
AbstractControl
— это базовый класс для всех контролов. Он предоставляет методы и свойства, которые позволяют управлять состоянием, валидацией и зависимостями полей формы.import { FormBuilder, FormGroup, Validators } from '@angular/forms';
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.form = this.fb.group({
password: ['', Validators.required],
confirmPassword: ['']
});
this.form.get('confirmPassword')?.setValidators([
this.matchPasswordsValidator(this.form.get('password'))
]);
}
matchPasswordsValidator(passwordControl: AbstractControl | null) {
return (confirmPasswordControl: AbstractControl) => {
const password = passwordControl?.value;
const confirmPassword = confirmPasswordControl.value;
return password === confirmPassword ? null : { passwordMismatch: true };
};
}
password
и confirmPassword
, автоматически реагируя на изменения первого поля. 22 Dec, 09:15
21 Dec, 14:15
unstable_batchedUpdates
?21 Dec, 08:06
20 Dec, 08:33
19 Dec, 15:10
useContextSelector
, который является улучшенной версией useContext
в React. Автор рассказывает, как этот хук позволяет оптимизировать производительность, минимизируя перерисовки компонентов, и предоставляет примеры его применения в больших проектах.19 Dec, 07:35
18 Dec, 08:31
29 Nov, 08:02
28 Nov, 14:36
28 Nov, 07:12
27 Nov, 06:52
26 Nov, 14:33
26 Nov, 07:29
25 Nov, 08:11
ngAfterContentInit
является жизненным циклом компонента, который вызывается после инициализации контента, переданного через ng-content
. Это позволяет выполнять операции над переданными дочерними элементами после того, как они станут частью DOM компонента. import { Component, ContentChild, AfterContentInit } from '@angular/core';
import { ElementRef } from '@angular/core';
@Component({
selector: 'app-card',
template: `<div class="card"><ng-content></ng-content></div>`
})
export class CardComponent implements AfterContentInit {
@ContentChild('header') header!: ElementRef;
ngAfterContentInit() {
if (!this.header) {
console.warn('Контент заголовка не передан!');
} else {
console.log('Заголовок загружен:', this.header.nativeElement.textContent);
}
}
}
CardComponent
проверяет наличие элемента header и логгирует его содержание при успешной инициализации.24 Nov, 09:15
23 Nov, 14:15
@HostListener
в Angular?23 Nov, 08:06
22 Nov, 08:33
21 Nov, 15:10
21 Nov, 07:35
20 Nov, 08:31
19 Nov, 15:21
19 Nov, 08:12
18 Nov, 07:43
ChangeDetectorRef
— инструмент в Angular, позволяющий управлять обнаружением изменений в компонентах вручную. Это особенно полезно, когда автоматическое обнаружение изменений (change detection
) не может уловить изменения состояния, например, при работе с асинхронными операциями или сторонними библиотеками, которые Angular не отслеживает по умолчанию.markForCheck()
и detectChanges()
позволяют более гибко управлять процессом обновления компонента. Например, если нужно обновить представление при изменении данных, полученных через сторонний API, можно вызвать detectChanges()
после обновления данных:import { ChangeDetectorRef } from '@angular/core';
@Component({
selector: 'app-example',
template: `<p>{{ data }}</p>`
})
export class ExampleComponent {
data: string;
constructor(private cdr: ChangeDetectorRef) {}
updateData(newData: string) {
this.data = newData;
this.cdr.detectChanges();
}
}
17 Nov, 09:13
16 Nov, 15:14
@Optional()
зависимость не найдена?16 Nov, 07:12
15 Nov, 08:02
14 Nov, 14:36
14 Nov, 07:12
13 Nov, 06:52
12 Nov, 14:33
12 Nov, 07:29
10 Nov, 18:07
@ViewChild
в Angular предоставляет доступ к элементам DOM и дочерним компонентам в шаблоне. Опция { static: true }
позволяет получить ссылку на элемент до инициализации представления, что полезно в случаях, когда к элементу нужно обратиться в ngOnInit
. @ViewChild
установлено { static: true }
, ссылка будет доступна в ngOnInit
, а не только в ngAfterViewInit
. Это может быть полезно для предварительной инициализации значений, которые зависят от состояния элементов шаблона. Например:@ViewChild('myElement', { static: true }) myElement!: ElementRef;
ngOnInit() {
console.log(this.myElement.nativeElement); // доступно уже здесь
}
*ngIf
, лучше использовать { static: false }
, так как это предотвратит ошибки в доступе к элементу.10 Nov, 09:15
09 Nov, 14:15
TrackBy
в Angular?08 Nov, 17:41
08 Nov, 15:40
08 Nov, 08:33
07 Nov, 15:10
FormData
, позволяющего собирать данные из форм. Она охватывает важные моменты, такие как работа с управляемыми и неуправляемыми формами, обработка данных в TypeScript, а также использование инструментов для валидации данных, таких как Zod. Также рассматриваются современные функции React и фреймворки, поддерживающие FormData
.06 Nov, 14:00
06 Nov, 08:31
05 Nov, 15:21
05 Nov, 08:12
04 Nov, 07:43
@HostListener
предоставляет удобный способ прослушивания событий, происходящих в DOM-элементах. Обычно он используется для стандартных событий, таких как клик, наведение мыши или прокрутка. Однако мало кто знает, что @HostListener
можно использовать для регистрации и обработки нестандартных событий, включая те, что определены разработчиком, или даже событий, происходящих за пределами стандартных браузерных API.import { Component, HostListener } from '@angular/core';
@Component({
selector: 'app-custom-event-listener',
template: `<p>Нажмите Shift + K, чтобы сработало событие.</p>`
})
export class CustomEventListenerComponent {
@HostListener('window:keydown', ['$event'])
handleKeyDown(event: KeyboardEvent) {
if (event.shiftKey && event.key === 'k') {
console.log('Комбинация Shift + K нажата!');
// Здесь можно вызывать любые действия
}
}
}
03 Nov, 09:13
02 Nov, 15:14
createPortal
в React?02 Nov, 07:12
01 Nov, 08:02
31 Oct, 14:36
click
, input
, blur
, change
, и submit
. В статье подробно описаны способы их использования для обработки взаимодействий пользователя с формами, полями ввода, кнопками и другими элементами интерфейса. 31 Oct, 07:12
30 Oct, 06:52
29 Oct, 14:33
29 Oct, 07:29
28 Oct, 08:11
@Optional()
в Angular используется для указания того, что зависимость может быть необязательной. Если нужная зависимость отсутствует, Angular не выбросит ошибку, а просто передаст null
. Это полезно, когда сервис или зависимость может не всегда быть доступна в контексте компонента.import { Component, Optional } from '@angular/core';
import { LoggingService } from './logging.service';
@Component({
selector: 'app-optional-demo',
template: `<p>Декоратор @Optional() пример</p>`
})
export class OptionalDemoComponent {
constructor(@Optional() private loggingService: LoggingService) {
if (this.loggingService) {
this.loggingService.log('Logging service is available');
} else {
console.log('Logging service is not available');
}
}
}
LoggingService
внедряется как необязательный. Если он не зарегистрирован, вместо ошибки просто будет выведено сообщение о его отсутствии.27 Oct, 09:15
26 Oct, 14:15
NgClass
?26 Oct, 08:06
25 Oct, 08:33
24 Oct, 15:10
@svg-use
для работы с SVG-иконками в JavaScript-приложениях, таких как React. Основное внимание уделено оптимизации загрузки SVG-файлов с помощью <use href>
, а не через инлайновые SVG, что снижает нагрузку на JS-бандлы и DOM. Также рассматриваются плюсы и минусы использования этой техники и перспективы для будущих стандартов веб-разработки.24 Oct, 07:35
23 Oct, 08:31
22 Oct, 15:21
22 Oct, 08:12
21 Oct, 07:43
*ngFor
в Angular используется для отображения списков, но часто приводит к излишним перерисовкам элементов при изменении данных. Это происходит, если Angular не может правильно сопоставить элементы и считает, что нужно перерисовать весь список. Метод trackBy
помогает Angular отслеживать изменения и определять, какие элементы нужно обновить.@Component({
selector: 'app-optimized-list',
template: `
<ul>
<li *ngFor="let item of items; trackBy: trackByFn">{{ item.name }}</li>
</ul>
`,
})
export class OptimizedListComponent {
items = [
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' },
{ id: 3, name: 'Item 3' },
];
trackByFn(index: number, item: any): number {
return item.id; // Уникальный идентификатор
}
}
id
как ключ, предотвращая перерисовку элементов при изменении содержимого.20 Oct, 09:13
19 Oct, 15:14
inject()
для инъекции зависимостей в Angular?19 Oct, 07:12
18 Oct, 08:02
17 Oct, 14:36
.git
для восстановления и применение файлов source maps
. Рассматриваются реальные кейсы из опыта авторов, примеры сборок и инструменты, которые помогают решить подобные задачи.17 Oct, 07:12
16 Oct, 06:52
15 Oct, 14:33
14 Oct, 16:12
14 Oct, 08:11
createPortal
в React позволяет рендерить компоненты вне текущей DOM-структуры. Это полезно для создания модальных окон, всплывающих меню или уведомлений, которые должны отображаться поверх остальных элементов без влияния родительских стилей и позиционирования.import React from 'react';
import ReactDOM from 'react-dom';
function Notification({ message }) {
return ReactDOM.createPortal(
<div className="notification">
{message}
</div>,
document.getElementById('notification-root')
);
}
Notification
рендерится в элемент с ID notification-root
, который находится вне основного DOM-дерева приложения. Это позволяет отображать уведомление поверх других компонентов без конфликтов стилей и вложенности.13 Oct, 09:15
12 Oct, 14:15
12 Oct, 08:06
11 Oct, 08:33
10 Oct, 15:10
10 Oct, 07:35
09 Oct, 08:31
08 Oct, 15:21