BehaviorSubject 值在不需要时返回。有时会重置实际需要的值
BehaviorSubject value is returned when not needed. Sometimes resets the value that is actually needed
我有一个按钮,用于更新组件的参数。当我按下按钮时,这会起作用,它会更新参数。有时,当我刷新页面或从外部页面通过 URL 导航至该页面时,更新逻辑不起作用。
我知道这是因为 behaviorSubject 被硬编码为 (2019,1,1,'Stores'),如下所示。为什么作者把它放在我不确定。我所知道的是刷新时不需要带有 (2019,1,1,'Stores')
的对象。我有一个方法 getSLGCurrentWeek()
也显示在下面,它应该将 (2019,1,1,'Stores')
更新为当前年、季度和周。现在是 2020 年 1,4。
为什么在我尝试重置时显示硬编码值?或者更好的是,什么是从 http 请求 getSLGCurrentWeek()
中获取正确值的最佳方法,以便我可以在 getSLGData(params)
方法中使用这些值?
export class SlgService {
private slgParamsSource: Subject<SLGReportParams> = new BehaviorSubject<SLGReportParams>(new SLGReportParams(2019, 1, 1, 'Stores'));
slgParams = this.slgParamsSource.asObservable();
constructor(private http: HttpClient, @Inject('BASE_URL') private baseUrl: string) { }
getSLGData(params: SLGReportParams) {
var slgParams = '?year=' + params.Year + '&quarter=' + params.Quarter + '&week=' + params.Week + '&dept=' + params.Dept;
return this.http.get(this.baseUrl + 'api/slg/slg' + slgParams);
}
getSLGCurrentWeek() {
return this.http.get(this.baseUrl + 'api/slg/SlgCurrentWeek');
}
getSLGWeeks() {
return this.http.get<any[]>(this.baseUrl + 'api/slg/slgGetAllWeeks');
}
updateSLGParams(params: SLGReportParams) {
this.slgParamsSource.next(params);
}
}
这是我的 ngOnInit()
ngOnInit() {
console.log("here")
this.slgForm = new FormGroup({
year: new FormControl(),
quarter: new FormControl(),
week: new FormControl(),
dept: new FormControl()
})
console.log(this.slgForm)
//subscribe to slg Service params observable
this.slgService.slgParams.subscribe(data => {
this.slgParams = data;
this.getData(this.slgParams);
})
this.slgService.getSLGCurrentWeek().subscribe((data: any) => {
//set SlgForm with current week values.
this.slgForm.patchValue({
year: data.year,
week: data.week,
quarter: data.quarter
})
this.slgParams = new SLGReportParams(this.slgForm.value.year, this.slgForm.value.quarter, this.slgForm.value.week, this.slgForm.value.dept);
this.slgService.updateSLGParams(this.slgParams);
//this.populateSLGTotals();
//this.operations(data);
this.getData(this.slgParams)
//update service with params // Submit has been taken out here
},
error => console.log(error),
)
}
更新按钮
submit() {
this.slgParams = new SLGReportParams(this.slgForm.value.year, this.slgForm.value.quarter, this.slgForm.value.week, this.slgForm.value.dept);
this.slgService.updateSLGParams(this.slgParams);
console.log("I have submitted")
}
总之。我如何 运行 this.slgService.getSLGCurrentWeek()
在不受 BehaviorSubject (2019,1,1,'Stores') 影响的情况下将参数放入 this.slgService.getSLGData(params)
?
感谢您的帮助。
Why is that hard coded value showing up when I am trying to reset it?
发生这种情况是因为您正在使用 BehaviorSubject
。您提供给 构造函数 的初始值就是您在执行
时最初获得的值
this.slgService.slgParams.subscribe(data => {
this.slgParams = data;
this.getData(this.slgParams);
})
这种主题的有趣之处在于它将缓存 最后发出的值。因此,新订阅者将收到该值。
这是我认为您可以使用 skip
operator.
跳过第一个发出的值的方法
this.slgService.slgParams
.pipe(skip(1))
.subscribe(data => {
this.slgParams = data;
this.getData(this.slgParams);
})
这些是非常有趣的代码片段。如果我处在你的位置,我会尝试做类似以下片段的事情。如果您可以在 stackblitz or enter link description here 中重现该问题,我可以为您提供完整的示例。
ngOnInit() {
this.slgForm = new FormGroup({
year: new FormControl(),
quarter: new FormControl(),
week: new FormControl(),
dept: new FormControl()
})
this.slgService.getSLGCurrentWeek().pipe(
map(data => {
this.slgForm.patchValue({
year: data.year,
week: data.week,
quarter: data.quarter
})
// Those are your slg params, that you will get as value from the stream
return new SLGReportParams(data.year, data.quarter, data.week, this.slgForm.value.dept)
}),
switchMap(slgParams => {
// This will return new stream, with the response of the get data http request
return this.slgService.getSLGData(slgParams);
})
).subscribe(resp => {
// Here you will have access to the data recieved from the getData function
console.log(resp)
})
}
所以我做了不同的事情,而不是依赖于服务内部的 BehaviorSubject
,我使用了更 functional/reactive 的方法,我在一个订阅,尝试删除对请求流外部数据的所有依赖。
你可以明白我的意思,通过查看我收集 slgParams
数据的方式,而不是依赖于具有修补值的表单,我直接从"source"(流中接收到的 data
对象)。
一条友好的建议,如果你打算在这个项目上工作更长的时间,我强烈建议你花一些时间学习反应式编程的原则,Angular,rxjs
, ngrx
.
如果我可以在这里为您的问题提出一些建议 => 您应该非常小心您的订阅:不要忘记 "unsubscribe" 通过实施 ngDestroy 来实现所有订阅。每次您加载组件时,它都会一次又一次地订阅。
如果你想有个主意:转到你的控制台,检查使用的内存,或者至少检查日志,你应该会在一段时间后看到它在屋顶上。
希望对您有所帮助。
我有一个按钮,用于更新组件的参数。当我按下按钮时,这会起作用,它会更新参数。有时,当我刷新页面或从外部页面通过 URL 导航至该页面时,更新逻辑不起作用。
我知道这是因为 behaviorSubject 被硬编码为 (2019,1,1,'Stores'),如下所示。为什么作者把它放在我不确定。我所知道的是刷新时不需要带有 (2019,1,1,'Stores')
的对象。我有一个方法 getSLGCurrentWeek()
也显示在下面,它应该将 (2019,1,1,'Stores')
更新为当前年、季度和周。现在是 2020 年 1,4。
为什么在我尝试重置时显示硬编码值?或者更好的是,什么是从 http 请求 getSLGCurrentWeek()
中获取正确值的最佳方法,以便我可以在 getSLGData(params)
方法中使用这些值?
export class SlgService {
private slgParamsSource: Subject<SLGReportParams> = new BehaviorSubject<SLGReportParams>(new SLGReportParams(2019, 1, 1, 'Stores'));
slgParams = this.slgParamsSource.asObservable();
constructor(private http: HttpClient, @Inject('BASE_URL') private baseUrl: string) { }
getSLGData(params: SLGReportParams) {
var slgParams = '?year=' + params.Year + '&quarter=' + params.Quarter + '&week=' + params.Week + '&dept=' + params.Dept;
return this.http.get(this.baseUrl + 'api/slg/slg' + slgParams);
}
getSLGCurrentWeek() {
return this.http.get(this.baseUrl + 'api/slg/SlgCurrentWeek');
}
getSLGWeeks() {
return this.http.get<any[]>(this.baseUrl + 'api/slg/slgGetAllWeeks');
}
updateSLGParams(params: SLGReportParams) {
this.slgParamsSource.next(params);
}
}
这是我的 ngOnInit()
ngOnInit() {
console.log("here")
this.slgForm = new FormGroup({
year: new FormControl(),
quarter: new FormControl(),
week: new FormControl(),
dept: new FormControl()
})
console.log(this.slgForm)
//subscribe to slg Service params observable
this.slgService.slgParams.subscribe(data => {
this.slgParams = data;
this.getData(this.slgParams);
})
this.slgService.getSLGCurrentWeek().subscribe((data: any) => {
//set SlgForm with current week values.
this.slgForm.patchValue({
year: data.year,
week: data.week,
quarter: data.quarter
})
this.slgParams = new SLGReportParams(this.slgForm.value.year, this.slgForm.value.quarter, this.slgForm.value.week, this.slgForm.value.dept);
this.slgService.updateSLGParams(this.slgParams);
//this.populateSLGTotals();
//this.operations(data);
this.getData(this.slgParams)
//update service with params // Submit has been taken out here
},
error => console.log(error),
)
}
更新按钮
submit() {
this.slgParams = new SLGReportParams(this.slgForm.value.year, this.slgForm.value.quarter, this.slgForm.value.week, this.slgForm.value.dept);
this.slgService.updateSLGParams(this.slgParams);
console.log("I have submitted")
}
总之。我如何 运行 this.slgService.getSLGCurrentWeek()
在不受 BehaviorSubject (2019,1,1,'Stores') 影响的情况下将参数放入 this.slgService.getSLGData(params)
?
感谢您的帮助。
Why is that hard coded value showing up when I am trying to reset it?
发生这种情况是因为您正在使用 BehaviorSubject
。您提供给 构造函数 的初始值就是您在执行
this.slgService.slgParams.subscribe(data => {
this.slgParams = data;
this.getData(this.slgParams);
})
这种主题的有趣之处在于它将缓存 最后发出的值。因此,新订阅者将收到该值。
这是我认为您可以使用 skip
operator.
this.slgService.slgParams
.pipe(skip(1))
.subscribe(data => {
this.slgParams = data;
this.getData(this.slgParams);
})
这些是非常有趣的代码片段。如果我处在你的位置,我会尝试做类似以下片段的事情。如果您可以在 stackblitz or enter link description here 中重现该问题,我可以为您提供完整的示例。
ngOnInit() {
this.slgForm = new FormGroup({
year: new FormControl(),
quarter: new FormControl(),
week: new FormControl(),
dept: new FormControl()
})
this.slgService.getSLGCurrentWeek().pipe(
map(data => {
this.slgForm.patchValue({
year: data.year,
week: data.week,
quarter: data.quarter
})
// Those are your slg params, that you will get as value from the stream
return new SLGReportParams(data.year, data.quarter, data.week, this.slgForm.value.dept)
}),
switchMap(slgParams => {
// This will return new stream, with the response of the get data http request
return this.slgService.getSLGData(slgParams);
})
).subscribe(resp => {
// Here you will have access to the data recieved from the getData function
console.log(resp)
})
}
所以我做了不同的事情,而不是依赖于服务内部的 BehaviorSubject
,我使用了更 functional/reactive 的方法,我在一个订阅,尝试删除对请求流外部数据的所有依赖。
你可以明白我的意思,通过查看我收集 slgParams
数据的方式,而不是依赖于具有修补值的表单,我直接从"source"(流中接收到的 data
对象)。
一条友好的建议,如果你打算在这个项目上工作更长的时间,我强烈建议你花一些时间学习反应式编程的原则,Angular,rxjs
, ngrx
.
如果我可以在这里为您的问题提出一些建议 => 您应该非常小心您的订阅:不要忘记 "unsubscribe" 通过实施 ngDestroy 来实现所有订阅。每次您加载组件时,它都会一次又一次地订阅。
如果你想有个主意:转到你的控制台,检查使用的内存,或者至少检查日志,你应该会在一段时间后看到它在屋顶上。
希望对您有所帮助。