Angular BehaviourSubject 只是有时被触发
Angular BehaviourSubject only being triggered sometimes
我有一个名为数据库的组件和一个服务 (DatabaseService
)。
然后我有一个具有当前数据库状态的 BehaviourSubject
,我想在 App 组件上获取该状态。
所以在 app.component.ts
我订阅了 BehaviourSubject
。
我从 BehaviourSubject 获取初始值,在数据库服务构造函数上调用 .next()
后获取该值,但是如果我在数据库组件上调用 .next()
我没有获取应用程序组件上的值。
我已经尝试将对 .next()
的调用放在数据库服务内部的一个方法上,但没有成功。
Database.component.ts
@Component({
selector: 'app-database',
templateUrl: './database.component.html',
styleUrls: ['./database.component.scss'],
providers: [DatabaseService]
})
export class DatabaseComponent implements OnInit, OnDestroy {
...
constructor(
private databaseService: DatabaseService,
) {
}
ngOnInit(): void {
...
}
updateDatabaseStatus(): void {
this.databaseService.databaseStatus.next(this.StatusId.value);
}
ngOnDestroy(): void {
...
}
}
database.service.ts
@Injectable({
providedIn: 'root'
})
export class DatabaseService {
public databaseStatus = new BehaviorSubject<DatabaseStatus>(DatabaseStatus.Open);
constructor(private api: ApiService) {
this.getSettingsDatabaseStatus().subscribe(data => {
this.databaseStatus.next(data[0].statusId);
});
}
public getSettingsDatabaseStatus(): Observable<Status> {
...
}
public updateCurrentDatabaseStatus(status: DatabaseStatus): void {
this.databaseStatus.next(status);
}
}
app.component.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy {
public databaseStatus = 'Open';
constructor(public router: Router,
private _api: ApiService,
private databaseService: DatabaseService) {
}
ngOnInit(): void {
this.databaseService.databaseStatus.subscribe(status => {
this.databaseStatus = DatabaseStatus[status];
});
}
ngOnDestroy(): void {
...
}
}
问题是您创建了多个 DatabaseService 实例。
在您的数据库服务中,代码 providedIn: 'root'
表示该服务的唯一实例将在您的应用程序的根目录中创建。也就是说,您的所有组件都可以访问该实例。
但是,在您的 database.component 中,您添加了代码 providers: [DatabaseService]
,该代码随后创建了该服务的一个新的、唯一的本地实例,该实例仅包含该组件会用。
我建议您从 database.component 中删除该代码,只在根级别提供服务。
此外,您肯定只想从 数据库服务 调用 .next()
函数。
例如,您的 database.component 代码如下所示:
@Component({
selector: 'app-database',
templateUrl: './database.component.html',
styleUrls: ['./database.component.scss']
})
export class DatabaseComponent implements OnInit, OnDestroy {
...
constructor(private databaseService: DatabaseService) {
}
ngOnInit(): void {
...
}
updateDatabaseStatus(): void {
this.databaseService.updateCurrentDatabaseStatus(this.StatusId.value);
}
ngOnDestroy(): void {
...
}
}
您应该可以保留您的 app.component 和 DatabaseService 代码。
我有一个名为数据库的组件和一个服务 (DatabaseService
)。
然后我有一个具有当前数据库状态的 BehaviourSubject
,我想在 App 组件上获取该状态。
所以在 app.component.ts
我订阅了 BehaviourSubject
。
我从 BehaviourSubject 获取初始值,在数据库服务构造函数上调用 .next()
后获取该值,但是如果我在数据库组件上调用 .next()
我没有获取应用程序组件上的值。
我已经尝试将对 .next()
的调用放在数据库服务内部的一个方法上,但没有成功。
Database.component.ts
@Component({
selector: 'app-database',
templateUrl: './database.component.html',
styleUrls: ['./database.component.scss'],
providers: [DatabaseService]
})
export class DatabaseComponent implements OnInit, OnDestroy {
...
constructor(
private databaseService: DatabaseService,
) {
}
ngOnInit(): void {
...
}
updateDatabaseStatus(): void {
this.databaseService.databaseStatus.next(this.StatusId.value);
}
ngOnDestroy(): void {
...
}
}
database.service.ts
@Injectable({
providedIn: 'root'
})
export class DatabaseService {
public databaseStatus = new BehaviorSubject<DatabaseStatus>(DatabaseStatus.Open);
constructor(private api: ApiService) {
this.getSettingsDatabaseStatus().subscribe(data => {
this.databaseStatus.next(data[0].statusId);
});
}
public getSettingsDatabaseStatus(): Observable<Status> {
...
}
public updateCurrentDatabaseStatus(status: DatabaseStatus): void {
this.databaseStatus.next(status);
}
}
app.component.ts
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy {
public databaseStatus = 'Open';
constructor(public router: Router,
private _api: ApiService,
private databaseService: DatabaseService) {
}
ngOnInit(): void {
this.databaseService.databaseStatus.subscribe(status => {
this.databaseStatus = DatabaseStatus[status];
});
}
ngOnDestroy(): void {
...
}
}
问题是您创建了多个 DatabaseService 实例。
在您的数据库服务中,代码 providedIn: 'root'
表示该服务的唯一实例将在您的应用程序的根目录中创建。也就是说,您的所有组件都可以访问该实例。
但是,在您的 database.component 中,您添加了代码 providers: [DatabaseService]
,该代码随后创建了该服务的一个新的、唯一的本地实例,该实例仅包含该组件会用。
我建议您从 database.component 中删除该代码,只在根级别提供服务。
此外,您肯定只想从 数据库服务 调用 .next()
函数。
例如,您的 database.component 代码如下所示:
@Component({
selector: 'app-database',
templateUrl: './database.component.html',
styleUrls: ['./database.component.scss']
})
export class DatabaseComponent implements OnInit, OnDestroy {
...
constructor(private databaseService: DatabaseService) {
}
ngOnInit(): void {
...
}
updateDatabaseStatus(): void {
this.databaseService.updateCurrentDatabaseStatus(this.StatusId.value);
}
ngOnDestroy(): void {
...
}
}
您应该可以保留您的 app.component 和 DatabaseService 代码。