Опциональные сервисы

Последнее обновление: 14.11.2023

Сервис может быть опциональным, необязательным. Например, в прошлой теме был создан сервис LogService:

export class LogService{
 
    write(logMessage:string){
         
        console.log(logMessage);
    }
}

И был другой сервис DataService, который использовал LogService:

import {Injectable} from "@angular/core";
import {LogService} from "./log.service";

@Injectable()
export class DataService{
 
    private data: string[] = [ "Tom", "Bob",  "Sam"];
    constructor(private logService: LogService){}
     
    getData(): string[] {
         
        this.logService.write("операция получения данных");
        return this.data;
    }
    addData(name: string){
         
        this.data.push(name);
        this.logService.write("операция добавления данных");
    }
}

Допустим, по какой-то причине сервис LogService не доступен для инжектирования, например, мы не добавили в провайдеры компонента AppComponent:

import { Component} from "@angular/core";
import { FormsModule } from "@angular/forms";
import {DataService} from "./data.service";

@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule],
    providers: [DataService],       // Добавлен только сервис DataService
    template: `<div>
        <div><input [(ngModel)]="name" />
            <button (click)="addItem(name)">Добавить</button>
        </div>
        <ul>
        @for(item of items; track $index){
            <li>{{item}}</li>
        }
        </ul>
    </div>`
})
export class AppComponent{ 
      
    items: string[] = [];
    name: string = "";
    constructor(private dataService: DataService){}
      
    addItem(name: string){
          
        this.dataService.addData(name);
    }
    ngOnInit(){
        this.items = this.dataService.getData();
    }
}

Если мы запустим приложение, то в этом случае мы получим ошибку. Так как для сервиса LogService не определен провайдер. В этом случае мы можем определить сервис LogService как опциональный, применяя декоратор Optional. Для этого изменим код DataService:

import {Injectable, Optional} from "@angular/core";
import {LogService} from "./log.service";

@Injectable()
export class DataService{
 
    private data: string[] = [ "Tom", "Bob",  "Sam"];
    constructor(@Optional() private logService: LogService){}
      
    getData(): string[] {
          
        if (this.logService) this.logService.write("операция получения данных");
        return this.data;
    }
    addData(name: string){
          
        this.data.push(name);
        if (this.logService) this.logService.write("операция добавления данных");
    }
}

Итак, в конструкторе класса мы получаем сервис как опциональный:

constructor(@Optional() private logService: LogService){}

Далее при обращении к сервису мы можем проверить, установлен ли он, и если он установлен, использовать его:

if (this.logService) this.logService.write("операция получения данных");
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850