Перейти к содержанию

Внедрение сервиса в другой сервис

Вполне вероятна ситуация, когда мы захотим использовать один сервис в другом сервисе. Например, в прошлой теме был создан сервис для работы с данными. Что если нам необходимо логгировать все операции с данными. Для логгирования определим новый сервис. Для этого добавим в папку src/app новый файл log.service.ts со следующим содержимым:

1
2
3
4
5
export class LogService {
    write(logMessage: string) {
        console.log(logMessage);
    }
}

Для логгирования в сервисе определен метод write, который выводит некоторое сообщение на консоль.

Теперь используем этот сервис. Для этого изменим код в файле data.service.ts:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { Injectable } from '@angular/core';
import { Phone } from './phone';
import { LogService } from './log.service';

@Injectable()
export class DataService {
    private data: Phone[] = [
        { name: 'Apple iPhone 7', price: 56000 },
        { name: 'HP Elite x3', price: 56000 },
        { name: 'Alcatel Idol S4', price: 25000 },
    ];
    constructor(private logService: LogService) {}

    getData(): Phone[] {
        this.logService.write('операция получения данных');
        return this.data;
    }
    addData(name: string, price: number) {
        this.data.push(new Phone(name, price));
        this.logService.write('операция добавления данных');
    }
}

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

Существует общая рекомендации от разработчиков Angular применять @Injectable к любому классу сервиса, хотя в принципе это необязательно.

Хотя в прошлой теме мы могли использовать сервис в компоненте без применения к компоненту декоратора @Injectable. Дело в том, что декоратор @Component, который применяется к компоненту, является подтипом @Injectable.

И также в случае с DataService сервис LogService также надо зарегистрировать в списке провайдеров AppComponent:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';
import { LogService } from './log.service';
import { Phone } from './phone';

@Component({
    selector: 'my-app',
    template: `
        <div class="panel">
            <div class="form-inline">
                <div class="form-group">
                    <div class="col-md-8">
                        <input
                            class="form-control"
                            [(ngModel)]="name"
                            placeholder="Модель"
                        />
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-6">
                        <input
                            type="number"
                            class="form-control"
                            [(ngModel)]="price"
                            placeholder="Цена"
                        />
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-md-offset-2 col-md-8">
                        <button
                            class="btn btn-default"
                            (click)="addItem(name, price)"
                        >
                            Добавить
                        </button>
                    </div>
                </div>
            </div>
            <table class="table table-striped">
                <thead>
                    <tr>
                        <th>Модель</th>
                        <th>Цена</th>
                    </tr>
                </thead>
                <tbody>
                    <tr *ngFor="let item of items">
                        <td>{{ item.name }}</td>
                        <td>{{ item.price }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    `,
    providers: [DataService, LogService],
})
export class AppComponent implements OnInit {
    items: Phone[] = [];
    constructor(private dataService: DataService) {}

    addItem(name: string, price: number) {
        this.dataService.addData(name, price);
    }
    ngOnInit() {
        this.items = this.dataService.getData();
    }
}

И несмотря на то, что напрямую LogService не используется в компоненте AppComponent, но он используется в DataService, который вызывается в AppComponent.

И при выполнении операций с данными в консоли браузера мы сможем увидеть работу сервиса LogService.

Скриншот приложения

Комментарии