Rxjs 中没有更新主题
Updation to subject is not happening in Rxjs
我正在尝试通过组件的方法更新 RxJS 主题。但它并没有正常发生。
cricketData$ = new Subject<string>();
ngOnChanges() {
this.cricketData$
.asObservable()
.pipe(
tap(() =>
console.log(
'Triggering REST call for cricket tab with the year ',
this.year
)
),
take(1)
)
.subscribe();
this.cricketData$.next('sachin');
}
updateCricketData() {
this.cricketData$.next('dravid');
}
如果我删除 take 运算符,主题就会更新。但是从下拉列表中选择值时会触发多个服务调用。 RxJS 中是否有任何其他运算符/方法可以实现以下场景?
- 从下拉列表中选择值时仅触发一次服务调用
- 主题也通过组件的方法更新
请参考下面的 StackBlitz link。提前致谢。
编辑器 URL Stackblitz:EditorURL
应用程序 URL Stackblitz:AppURL
有两个问题。
第一个:
ngOnChanges
触发多次,每次更改值时都会添加一个并行工作的新管道。
take(1)
使您之前的管道停止并且仅触发最近的管道 tab
。
ngOnInit(): void { // runs once
this.cricketData$
.asObservable()
.pipe( // runs on every next
tap(() =>
console.log(
'Triggering REST call for cricket tab with the year ',
this.year
)
)
)
.subscribe();
}
ngOnChanges() {
this.cricketData$.next('sachin'); // runs on every event on the page
}
第二个问题:你真的想在页面有更新时在 ngChange 上触发这个功能,而不仅仅是下拉列表吗?在下拉列表中进行更改,然后您可以使用 Input set year(value: string)
的组合
export class CricketComponent implements OnChanges {
private _selectedYear: string;
@Input() set year(value: string) {
this._selectedYear = value;
this.cricketData$.next('sachin'); // will trigger with every drop down change
}
cricketData$ = new Subject<string>();
constructor() {}
ngOnInit(): void {
this.cricketData$
.asObservable()
.pipe(
tap((value) =>
console.log(
'Triggering REST call for cricket tab with the year ',
this._selectedYear,
value
)
)
)
.subscribe();
}
ngOnChanges() {}
updateCricketData() {
this.cricketData$.next('dravid');
}
}
如何为年份选择器使用表单控件,我们可以监听表单控件和您使用 combineLatest
创建的主题的变化,这将在它们中的任何一个发出时触发(只要它们至少发出过一次)。不知道您 how/when 的确切情况,您的主题最初已更新,所以我只是添加了一个 startWith(null)
值。将其应用于您的用例...
因此 parent 的表单控件:
year = new FormControl(2019);
和模板,我们在其中标记表单控件并将表单控件传递给 child:
<select [formControl]="year">
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
</select>
<app-cricket [year]="year"></app-cricket>
然后 child 在 OnInit
中与主题一起收听此内容:
ngOnInit() {
combineLatest([
this.year.valueChanges.pipe(startWith(this.year.value)),
this.cricketData$.asObservable().pipe(startWith(null)),
]).pipe(
switchMap(values => {
return REST API request...
})
).subscribe(result => console.log(result))
}
使用startWith
使它们最初触发。记得取消订阅!!
STACKBLITZ(没有 switchMap
)
我正在尝试通过组件的方法更新 RxJS 主题。但它并没有正常发生。
cricketData$ = new Subject<string>();
ngOnChanges() {
this.cricketData$
.asObservable()
.pipe(
tap(() =>
console.log(
'Triggering REST call for cricket tab with the year ',
this.year
)
),
take(1)
)
.subscribe();
this.cricketData$.next('sachin');
}
updateCricketData() {
this.cricketData$.next('dravid');
}
如果我删除 take 运算符,主题就会更新。但是从下拉列表中选择值时会触发多个服务调用。 RxJS 中是否有任何其他运算符/方法可以实现以下场景?
- 从下拉列表中选择值时仅触发一次服务调用
- 主题也通过组件的方法更新
请参考下面的 StackBlitz link。提前致谢。
编辑器 URL Stackblitz:EditorURL
应用程序 URL Stackblitz:AppURL
有两个问题。
第一个:
ngOnChanges
触发多次,每次更改值时都会添加一个并行工作的新管道。
take(1)
使您之前的管道停止并且仅触发最近的管道 tab
。
ngOnInit(): void { // runs once
this.cricketData$
.asObservable()
.pipe( // runs on every next
tap(() =>
console.log(
'Triggering REST call for cricket tab with the year ',
this.year
)
)
)
.subscribe();
}
ngOnChanges() {
this.cricketData$.next('sachin'); // runs on every event on the page
}
第二个问题:你真的想在页面有更新时在 ngChange 上触发这个功能,而不仅仅是下拉列表吗?在下拉列表中进行更改,然后您可以使用 Input set year(value: string)
export class CricketComponent implements OnChanges {
private _selectedYear: string;
@Input() set year(value: string) {
this._selectedYear = value;
this.cricketData$.next('sachin'); // will trigger with every drop down change
}
cricketData$ = new Subject<string>();
constructor() {}
ngOnInit(): void {
this.cricketData$
.asObservable()
.pipe(
tap((value) =>
console.log(
'Triggering REST call for cricket tab with the year ',
this._selectedYear,
value
)
)
)
.subscribe();
}
ngOnChanges() {}
updateCricketData() {
this.cricketData$.next('dravid');
}
}
如何为年份选择器使用表单控件,我们可以监听表单控件和您使用 combineLatest
创建的主题的变化,这将在它们中的任何一个发出时触发(只要它们至少发出过一次)。不知道您 how/when 的确切情况,您的主题最初已更新,所以我只是添加了一个 startWith(null)
值。将其应用于您的用例...
因此 parent 的表单控件:
year = new FormControl(2019);
和模板,我们在其中标记表单控件并将表单控件传递给 child:
<select [formControl]="year">
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
</select>
<app-cricket [year]="year"></app-cricket>
然后 child 在 OnInit
中与主题一起收听此内容:
ngOnInit() {
combineLatest([
this.year.valueChanges.pipe(startWith(this.year.value)),
this.cricketData$.asObservable().pipe(startWith(null)),
]).pipe(
switchMap(values => {
return REST API request...
})
).subscribe(result => console.log(result))
}
使用startWith
使它们最初触发。记得取消订阅!!
STACKBLITZ(没有 switchMap
)