Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度RxJS-设置值将管道值更改为null,直到可观察到的值被解析_Javascript_Angular_Typescript_Rxjs - Fatal编程技术网

Javascript 角度RxJS-设置值将管道值更改为null,直到可观察到的值被解析

Javascript 角度RxJS-设置值将管道值更改为null,直到可观察到的值被解析,javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,我正试图通过管道从选择来触发相应的API请求,并在未收到响应时显示微调器。除此之外,我还尝试使用publish()和refCount(),这样我就可以在模板中的多个位置使用async管道的可观察性 my component.ts my component.html 然后它就可以正常工作了,只需要向服务器发出一个fire's off 1请求。但当您更改select选项时,results$|async在新值可用之前不再计算为null。相反,它坚持使用旧的值,然后突然用更新的值替换它。理想情况下,

我正试图通过管道从
选择
来触发相应的API请求,并在未收到响应时显示微调器。除此之外,我还尝试使用
publish()
refCount()
,这样我就可以在模板中的多个位置使用
async
管道的可观察性

my component.ts

my component.html


然后它就可以正常工作了,只需要向服务器发出一个fire's off 1请求。但当您更改select选项时,
results$|async
在新值可用之前不再计算为
null
。相反,它坚持使用旧的值,然后突然用更新的值替换它。

理想情况下,您希望分离变量-以便上下文更清楚-加载的状态和最终的
结果是两件不同的事情。假设
结果
等同于
状态
正在加载可能是危险的,因为它们根本不同。例如,如果出现错误会发生什么?这意味着
结果
为空,但
状态
不再加载。如果遵循您的实现,当抛出错误时,您的微调器将永远处于加载状态。而且它也可能会运行到您描述的场景中-您失去了加载的状态,因为现在它不再是空的,并且您的微调器在第一个初始请求之后将永远不会加载

每次更改表单时,将
结果
重置为
null
也有点多余(毫无意义)。从技术上讲,您的结果不是
null
。它有结果。只是结果不是最新的

相反,请使用主题来发射值:

private isLoading = new BehaviourSubject<boolean>(false);
并让您的html绑定到它:

<mat-progress-spinner *ngIf="isLoading"></mat-progress-spinner>


让我把你的问题答对。您希望:当您更改选择选项时,
results$|async
应更改为
null
,直到新值可用?是的,这是正确的。尝试使用
(results)?.name
isLoading
不能是私有的,我们应该绑定到
isLoading | async
。但这根本不会触发请求,因为使用
results$
的div将具有
*ngIf=“!load”
。因此,没有人订阅
结果$
。我尝试使用
*ngIf=“(results$| async)&&&&!loading”
,这会触发请求,但我得到错误
无法再次读取null的属性“name”
。同意您的“关注点分离”参数。顺便说一句,“冗余”和“无意义”并不像您所建议的那样是同义词。在重新加载结果时将其重置为null既不是多余的,也不是毫无意义的,这取决于需求。
<mat-progress-spinner *ngIf="!(results$ | async)"></mat-progress-spinner>

<div *ngIf="(results$ | async) as results">
   <p>Name {{(results).name}}</p>
   <small>{{(results).description}}
</div>
private isLoading = new BehaviourSubject<boolean>(false);
this.results$ = this.selectControl.valueChanges.pipe(
    startWith('hard'),
    tap(() => this.isLoading.next(true)), //sets loading to true, we are firing our api request!
    switchMap((evalStrategy: 'hard' | 'soft') => this.apiService.getResults(evalStrategy)),
    tap(() => this.isLoading.next(false)), //api finished fetching, stop the spinner!
    catchError(() => this.isLoading.next(false)), //this is up to you on how you want to do error handling.
    publish(),
    refCount(),
);
<mat-progress-spinner *ngIf="isLoading"></mat-progress-spinner>