当我在 BehaviorSubject 上调用函数 next 时,订阅函数没有被触发
Subscribe function is not trigger when I call function next on BehaviourSubject
我有 2 个组件和一个在这 2 个组件之间共享的服务,比方说 ComponentA 和 ComponentB。应用程序工具栏的一个组件 (Comp. A) 和另一个组件 B,使用路由模块进行路由。这是 HTML:
<a></a>
<router-outlet></router-outlet>
之所以采用这种方式,是因为我希望始终将工具栏固定在顶部。
在组件 A 的 HTML 中,我有一个 select 到 select 应用程序的语言。在组件 B 中,我有一些来自后端的内容,具体取决于 selected language.I 希望当用户更改语言时,内容来自服务器,rendered.I 正在使用该服务调用后端并呈现新内容。我的问题来了,对服务器的调用已经完成并且没问题,但它从未进入订阅功能。我曾尝试使用共享模块(有或没有 forRoot()),我试图使该服务成为模块的提供者,并在另一个模块(AppModule)中导入模块(AppRoutingModule)。在这一刻,我到了控制台出现 "No provider for Service!" 错误的地步。服务和组件的代码:
服务:
@Injectable()
export class SharedService extends GlobalHttpService<HomeSection> {
private sectionsSubject: BehaviorSubject<HomeSection[]>;
constructor(private http: HttpClient) {
super("api/path", new GlobalSerializer(HomeSection), http);
this.sectionsSubject = new BehaviorSubject<HomeSection[]>([]);
}
load() {
this.list().subscribe(res => {
this.sectionsSubject.next(res);
});
}
get content() {
return this.sectionsSubject.asObservable();
}
}
AppModule
@NgModule({
imports:[AppRoutingModule]
})
export class AppModule {}
AppRoutingModule
export function SharedServiceFactory(http: HttpClient){
return new SharedServiceFactory(http);
}
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [
{
provide: SectionService,
useFactory: SectionServiceFactory,
deps: [HttpClient]
}
]
})
export class AppRoutingModule {}
组件A:
@Component({
selector: "a",
templateUrl: ".a.component.html",
styleUrls: ["./a.component.scss"]
})
export class AComponent implements OnInit {
constructor(
public authentificationService: AuthenticationService,
private languagesService: LanguagesService,
private sharedService: SharedService
) {
}
ngOnInit() {
//other logic;
}
updateLanguage(event) {
// other logic;
this.sharedService.load();
}
组件B
@Component({
selector: "app-b",
templateUrl: "./b.component.html",
styleUrls: ["./b.component.scss"]
})
export class BComponent implements OnInit {
constructor(
private sharedService: SharedService,
) {}
ngOnInit() {
this.sharedService.load();
this.sharedService.content.subscribe(s => {
// logic
});
}
如何才能拥有 SharedService 的单个实例,或者我能否将一个模块包含在另一个模块中?
尝试在您的服务中这样做:
@Injectable({ providedIn: 'root' })
并从 AppRoutingModule 中删除提供此服务。
如果您使用 providedIn: 'root'
,则无需在其他地方提供。它将在 Angular 树的最顶端注入服务,因此您将始终拥有相同的实例。它的另一个好处 - 它使服务可摇树。
首先在AppModule中导入服务:
AppModule
@NgModule({
imports:[AppRoutingModule],
providers: [SharedService]
})
export class AppModule {}
或:
@Injectable({ providedIn: 'root' })
导出 class SharedService 扩展 GlobalHttpService {
...
}
然后,您不必在 SharedService 中创建一个方法来 return Observable 事件,您可以只在构造函数中创建一个 属性 和实例一次。
SharedService
@Injectable()
export class SharedService extends GlobalHttpService<HomeSection> {
private sectionsSubject: BehaviorSubject<HomeSection[]>;
public content$: Observable<HomeSection[]>;
constructor(private http: HttpClient) {
super("api/path", new GlobalSerializer(HomeSection), http);
this.sectionsSubject = new BehaviorSubject<HomeSection[]>([]);
this.content$ = this.sectionsSubject.asObservable();
}
load() {
this.list().subscribe(res => {
this.sectionsSubject.next(res);
});
}
}
最后在你的组件 B 中:
@Component({
selector: "app-b",
templateUrl: "./b.component.html",
styleUrls: ["./b.component.scss"]
})
export class BComponent implements OnInit {
constructor(
private sharedService: SharedService,
) {}
ngOnInit() {
this.sharedService.load();
this.sharedService.content$.subscribe(s => {
// logic
});
}
我有 2 个组件和一个在这 2 个组件之间共享的服务,比方说 ComponentA 和 ComponentB。应用程序工具栏的一个组件 (Comp. A) 和另一个组件 B,使用路由模块进行路由。这是 HTML:
<a></a>
<router-outlet></router-outlet>
之所以采用这种方式,是因为我希望始终将工具栏固定在顶部。 在组件 A 的 HTML 中,我有一个 select 到 select 应用程序的语言。在组件 B 中,我有一些来自后端的内容,具体取决于 selected language.I 希望当用户更改语言时,内容来自服务器,rendered.I 正在使用该服务调用后端并呈现新内容。我的问题来了,对服务器的调用已经完成并且没问题,但它从未进入订阅功能。我曾尝试使用共享模块(有或没有 forRoot()),我试图使该服务成为模块的提供者,并在另一个模块(AppModule)中导入模块(AppRoutingModule)。在这一刻,我到了控制台出现 "No provider for Service!" 错误的地步。服务和组件的代码: 服务:
@Injectable()
export class SharedService extends GlobalHttpService<HomeSection> {
private sectionsSubject: BehaviorSubject<HomeSection[]>;
constructor(private http: HttpClient) {
super("api/path", new GlobalSerializer(HomeSection), http);
this.sectionsSubject = new BehaviorSubject<HomeSection[]>([]);
}
load() {
this.list().subscribe(res => {
this.sectionsSubject.next(res);
});
}
get content() {
return this.sectionsSubject.asObservable();
}
}
AppModule
@NgModule({
imports:[AppRoutingModule]
})
export class AppModule {}
AppRoutingModule
export function SharedServiceFactory(http: HttpClient){
return new SharedServiceFactory(http);
}
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [
{
provide: SectionService,
useFactory: SectionServiceFactory,
deps: [HttpClient]
}
]
})
export class AppRoutingModule {}
组件A:
@Component({
selector: "a",
templateUrl: ".a.component.html",
styleUrls: ["./a.component.scss"]
})
export class AComponent implements OnInit {
constructor(
public authentificationService: AuthenticationService,
private languagesService: LanguagesService,
private sharedService: SharedService
) {
}
ngOnInit() {
//other logic;
}
updateLanguage(event) {
// other logic;
this.sharedService.load();
}
组件B
@Component({
selector: "app-b",
templateUrl: "./b.component.html",
styleUrls: ["./b.component.scss"]
})
export class BComponent implements OnInit {
constructor(
private sharedService: SharedService,
) {}
ngOnInit() {
this.sharedService.load();
this.sharedService.content.subscribe(s => {
// logic
});
}
如何才能拥有 SharedService 的单个实例,或者我能否将一个模块包含在另一个模块中?
尝试在您的服务中这样做:
@Injectable({ providedIn: 'root' })
并从 AppRoutingModule 中删除提供此服务。
如果您使用 providedIn: 'root'
,则无需在其他地方提供。它将在 Angular 树的最顶端注入服务,因此您将始终拥有相同的实例。它的另一个好处 - 它使服务可摇树。
首先在AppModule中导入服务:
AppModule
@NgModule({
imports:[AppRoutingModule],
providers: [SharedService]
})
export class AppModule {}
或:
@Injectable({ providedIn: 'root' }) 导出 class SharedService 扩展 GlobalHttpService { ... }
然后,您不必在 SharedService 中创建一个方法来 return Observable 事件,您可以只在构造函数中创建一个 属性 和实例一次。
SharedService
@Injectable()
export class SharedService extends GlobalHttpService<HomeSection> {
private sectionsSubject: BehaviorSubject<HomeSection[]>;
public content$: Observable<HomeSection[]>;
constructor(private http: HttpClient) {
super("api/path", new GlobalSerializer(HomeSection), http);
this.sectionsSubject = new BehaviorSubject<HomeSection[]>([]);
this.content$ = this.sectionsSubject.asObservable();
}
load() {
this.list().subscribe(res => {
this.sectionsSubject.next(res);
});
}
}
最后在你的组件 B 中:
@Component({
selector: "app-b",
templateUrl: "./b.component.html",
styleUrls: ["./b.component.scss"]
})
export class BComponent implements OnInit {
constructor(
private sharedService: SharedService,
) {}
ngOnInit() {
this.sharedService.load();
this.sharedService.content$.subscribe(s => {
// logic
});
}