我试图在某个可观察的某个观察开始时立即在按钮内显示一个微调器,并在它结束时立即再次隐藏它。
经过几个小时的研究,我有点失去了如何实现它(我知道这里有几个帖子,但似乎没有任何帮助,甚至经常提到的角度2忙或其中一个&#39 ; s叉子真的不起作用)
所以工作流程将是
我有一个指令/组件,我可以通过@Input提供一个Observable。 然后,该指令应该在Observable启动后立即显示微调器(或者我可以使用click事件)。 并且它应该在订阅完成时再次隐藏微调器。
注意:以下示例是简化的(不涉及微调器等),但确切地显示了问题所在。
export class AppComponent {
name = 'Angular 6';
test: Observable<any>;
constructor(private http: HttpClient) {
const obs = of(true);
this.test = obs.pipe(tap(() => console.log('tap1')), flatMap(() => {
return this.http.get('https://httpbin.org/get');
})
);
}
demo() {
this.test.subscribe((state: any) => console.log(state));
}
}
export class HelloComponent implements OnChanges {
@Input() name: string;
@Input()
obs: Observable<any>;
ngOnChanges(changes: SimpleChanges): void {
if (changes.obs) {
this.obs.pipe(map(() => console.log('component')));
}
}
}
here is the stackblitz说明了我试图完成的事情以及它目前无法正常工作
当我在subscribe
中调用hello-component
时,它显然会执行每个管道方法,这不是我想要的。
当我不打电话subscribe
时,pipe
运算符会创建一个显然永远不会被执行的新subscription
。
所需的行为是控制台中的以下输出。
我感觉我错过了一些非常明显的东西。 关于如何解决这个问题的任何想法?
答案 0 :(得分:1)
使用async
和模板可以让像spinner这样的案例更轻松:
<ng-container *ngIf="person$ | async as person; else loading">
{{person.name}}
</ng-container>
<ng-template #loading>
loading...
</ng-template>
答案 1 :(得分:0)
不完全确定您希望如何执行此操作,但我扩展了您的Stackbiltz with a solution here。
主要部分是:
showSpinner = false;
demo() {
this.showSpinner = true;
this.test.subscribe(
tick => (console.log("event from observable")),
error => (console.log("error from observable")),
() => {console.log("Observable finished"); this.showSpinner=false;}
)
}
observable有3种事件类型:&#34; tick&#34;将获取每个Observable.next,错误时调用错误,并在最后一个事件之后(如果事件流结束)将调用最后一次,最后一次调用。你应该利用它。
修改强>: 您可以在Observable定义中使用管道和点击:
this.obs.pipe(
tap(
event => (console.log("observable event tick")),
error => (console.log("observable error")),
() => (console.log("observable finish"))
)
);
Edit2 :我已将代码移至this example here中的hello.component.ts
。
编辑3 :你不能听听听众&#34;。但是,您可以更改逻辑,以实现所需行为,请参阅this updated example。
基本上,您需要显式调用组件,以通知它有关spinnning事件的开始和结束事件。您可以使用@ViewChild
查看组件,然后直接调用其公共方法。