Класс Subject
импортируется из rxjs/Subject
. Данный класс объединяет observable
и observer
в одном объекте. Он реализует следующие методы:
Для отправки данных используется метод next()
.
Для принятия данных метод subscribe()
.
Для отписки unsubscribe()
.
Хорошей практикой является реализовать сервис на основе Subject
и использовать его как альтернативу Emit
.
Рассмотрим пример создания простого сервиса на основе класса Subject
и то как его можно использования в различных компонентах. Один из компонентов будет реализовывать метод next()
, для формирования потока. Второй компонент будет наблюдать и реагировать на изменения данного потока.
Для начала создадим сервис UsersService
в файле \app\users.service.ts
:
import { Subject } from 'rxjs/Subject'; | |
export class UsersService { | |
userActivated = new Subject(); | |
} |
Затем, нам нужно зарегистровать этот сервис в провайдерах app.module.ts
:
import { BrowserModule } from '@angular/platform-browser'; | |
import { NgModule } from '@angular/core'; | |
import { AppComponent } from './app.component'; | |
import { HomeComponent } from './home/home.component'; | |
import { UserComponent } from './user/user.component'; | |
import { AppRoutingModule } from './app-routing.module'; | |
import { UsersService } from './users.service'; | |
@NgModule({ | |
declarations: [ | |
AppComponent, | |
HomeComponent, | |
UserComponent | |
], | |
imports: [ | |
BrowserModule, | |
AppRoutingModule | |
], | |
providers: [UsersService], // имя сервиса нужно передать в массив ключа providers | |
bootstrap: [AppComponent] | |
}) | |
export class AppModule { } |
В шаблоне observable
компонента поставим обработчик на событие click
для запуска метода onActivate()
:
<p>User with <strong>ID {{ id }}</strong> was loaded</p> | |
<button class="btn btn-primary" (click)="onActivate()">Activate!</button> |
Метод onActivate()
использует метод next()
для формирования потока:
import { Component, OnInit } from '@angular/core'; | |
import { ActivatedRoute, Params } from '@angular/router'; | |
import { UsersService } from '../users.service'; | |
@Component({ | |
selector: 'app-user', | |
templateUrl: './user.component.html', | |
styleUrls: ['./user.component.css'] | |
}) | |
export class UserComponent implements OnInit { | |
id: number; | |
constructor(private route: ActivatedRoute, private usersService: UsersService) { } | |
//... | |
onActivate() { | |
this.usersService.userActivated.next(this.id); | |
} | |
} |
И наконец, так выглядит подписка в компоненте реализующем наблюдателя:
import { Component, OnInit } from '@angular/core'; | |
import { UsersService } from './users.service'; | |
@Component({ | |
selector: 'app-root', | |
templateUrl: './app.component.html', | |
styleUrls: ['./app.component.css'] | |
}) | |
export class AppComponent implements OnInit { | |
user1Activated = false; | |
user2Activated = false; | |
constructor(private usersService: UsersService) {} | |
ngOnInit() { | |
this.usersService.userActivated.subscribe( | |
(id: number) => { | |
if (id === 1) { | |
this.user1Activated = true; | |
} else if (id === 2) { | |
this.user2Activated = true; | |
} | |
} | |
); | |
} | |
} |
Таким образом, на основании переданного id меняется состояние компонента, в котором реализуется наблюдение за observable
.