Фото: Timothy Cuenat на Unsplash
В сучасних додатках на Angular часто виникає потреба в обміні даними та функціональністю між компонентами. Спільні сервіси є елегантним рішенням цієї проблеми, сприяючи повторному використанню коду та підтримці єдиного джерела істини. Давайте детальніше розглянемо, як працюють спільні сервіси в Angular, та найкращі практики їх впровадження.
Що таке спільні сервіси?
Спільні сервіси в Angular — це сінглетон-екземпляри, які можуть бути впроваджені в кілька компонентів або інші сервіси. Вони виступають як центральний репозиторій для даних і методів, до яких необхідно мати доступ по всьому додатку. Використовуючи ін'єкцію залежностей, Angular гарантує, що всі компоненти отримують один і той самий екземпляр сервісу.
Створення спільного сервісу
Давайте створимо простий спільний сервіс, щоб краще зрозуміти цей концепт:
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserService {
private currentUserSubject = new BehaviorSubject(null);
currentUser$ = this.currentUserSubject.asObservable();
constructor() { }
setUser(user: any): void {
this.currentUserSubject.next(user);
}
getUser(): Observable {
return this.currentUser$;
}
clearUser(): void {
this.currentUserSubject.next(null);
}
}
Використання сервісу в компонентах
Ось як ви можете використовувати спільний сервіс у кількох компонентах:
// first.component.ts
@Component({
selector: 'app-first',
template: `
Welcome, {{ user.name }}!
Update User
` }) export class FirstComponent implements OnInit { user$ = this.userService.currentUser$; constructor(private userService: UserService) { } updateUser(): void { this.userService.setUser({ name: 'John Doe', role: 'Admin' }); } } // second.component.ts @Component({ selector: 'app-second', template: `
User Role: {{ user.role }}
` }) export class SecondComponent implements OnInit { user$ = this.userService.currentUser$; constructor(private userService: UserService) { } } ```
## Кращі практики для спільних сервісів
## 1. Використовуйте відповідний обсяг
При наданні сервісів вибирайте правильний обсяг залежно від ваших потреб:
// Рівень кореня (сінглетон по всьому додатку)
@Injectable({
providedIn: 'root'
})
// Рівень модуля функціональності
@Injectable({
providedIn: YourFeatureModule
})
// Рівень компонента (новий екземпляр для кожного компонента)
@Component({
providers: [YourService]
})
```
2. Реалізуйте керування станом
Для складних додатків розгляньте можливість впровадження правильного керування станом:
export interface AppState {
user: User | null;
theme: string;
settings: AppSettings;
}
@Injectable({
providedIn: 'root'
})
export class StateService {
private state = new BehaviorSubject(initialState);
state$ = this.state.asObservable();
updateState(newState: Partial): void {
this.state.next({
...this.state.value,
...newState
});
}
}
3. Керуйте пам'яттю
Завжди підписуйтеся на спостерігачів, щоб уникнути витоків пам'яті:
export class YourComponent implements OnInit, OnDestroy {
private destroy$ = new Subject();
ngOnInit(): void {
this.userService.currentUser$
.pipe(takeUntil(this.destroy$))
.subscribe(user => {
// Обробка даних користувача
});
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
Загальні випадки використання спільних сервісів
- Сервіс автентифікації: Управління станом автентифікації користувачів по всьому додатку
- Сервіс теми: Обробка глобальних налаштувань теми додатку
3.
Сервіс кешування даних: Кешування відповідей API для кращої продуктивності - Сервіс конфігурації: Управління конфігурацією додатку
- Сервіс обробки помилок: Централізація логіки обробки помилок
Тестування спільних сервісів
Ось приклад того, як можна протестувати спільний сервіс:
describe('UserService', () => {
let service: UserService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [UserService]
});
service = TestBed.inject(UserService);
});
it('should update user data', (done) => {
const testUser = { name: 'Test User', role: 'User' };
service.currentUser$.subscribe(user => {
if (user) {
expect(user).toEqual(testUser);
done();
}
});
service.setUser(testUser);
});
});
Висновок
Спільні сервіси є потужною можливістю в Angular, що допомагає підтримувати чисті, легко підтримувані та масштабовані додатки. Дотримуючись кращих практик, описаних вище, і розуміючи різноманітні варіанти використання, ви зможете ефективно впроваджувати спільні сервіси у свої Angular-додатки.
Пам'ятайте:
- Вибирайте відповідний обсяг для ваших сервісів
- Реалізуйте правильне управління станом для складних додатків
- Уважно ставтесь до управління пам'яттю
- Пишіть повні тести для своїх сервісів
З цими настановами ви будете добре підготовлені для створення надійних Angular-додатків за допомогою спільних сервісів.
Перекладено з: Understanding Shared Services in Angular: A Comprehensive Guide