typescript Angular2 表单控件 valueChanges 可观察完成从未调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37531619/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular2 form control valueChanges observable complete never called
提问by EldarGranulo
I'm currently trying to show a simple loader on my search bar while the searching is taking place. I have planned to set a variable in the subscribe callback on the valueChanges
observable from my form control to a value "loading", and to set it to an empty string in the complete callback. However, the complete callback is never called.
我目前正在尝试在搜索时在我的搜索栏上显示一个简单的加载程序。我计划在valueChanges
表单控件的observable上的订阅回调中设置一个变量为值“加载”,并在完整回调中将其设置为空字符串。但是,永远不会调用完整的回调。
I have also tried adding a callback to finally on the observable, but it is also never called.
我还尝试在可观察对象的 finally 中添加回调,但它也从未被调用过。
My code:
我的代码:
searchBox: Control = new Control();
loadingClass: string = "";
constructor() {
this.searchBox.valueChanges
.debounceTime(400)
.distinctUntilChanged()
.subscribe((text: string) => {
this.imageSearch = text;
this.loadingClass = "loading";
}, (err: Error) => {
console.log(err);
}, () => {
this.loadingClass = "";
console.log("test");
});
}
采纳答案by EldarGranulo
I figured out that I'm trying the wrong approach. Instead, I realized I had debounceTime
on my observable, so I registered a keyup
event on my input control, and in it set the value of loadingClass
to "loading"
, and in my subscribe I set the value back to an empty string.
我发现我正在尝试错误的方法。相反,我意识到我debounceTime
在我的 observable 上有,所以我keyup
在我的输入控件上注册了一个事件,并在其中设置了loadingClass
to的值"loading"
,并在我的订阅中将值设置回一个空字符串。
回答by Thierry Templier
It's normal since the observable is never completed. The valueChanges
allows you to receive value from your search box. In fact, you want to be notified when the search action is complete.
这是正常的,因为 observable 永远不会完成。将valueChanges
允许你收到从搜索框的值。实际上,您希望在搜索操作完成时收到通知。
So I would try something like that, assuming that the searchImage
actually does the search and return an observable:
所以我会尝试类似的东西,假设searchImage
实际上进行搜索并返回一个可观察的:
constructor() {
this.searchBox.valueChanges
.debounceTime(400)
.distinctUntilChanged()
.flatMap((text:string) => { // <-------
this.loadingClass = "loading";
return this.searchImage(text);
})
.subscribe((searchResult) => {
this.imageSearch = searchResult;
this.loadingClass = ""; // <----
}, (err: Error) => {
console.log(err);
});
}
See this article for the use of the flatMap
operator:
flatMap
操作符的使用见这篇文章:
回答by Luillyfe
I hope this could lead some people to get a better understanding of Angular2 Forms. Angular has two different approaches of building forms (Reactive and Template form). Not being aware of this could lead you to messy apps.
我希望这可以引导一些人更好地理解 Angular2 Forms。Angular 有两种不同的构建表单的方法(反应式和模板表单)。不知道这一点可能会导致您使用杂乱的应用程序。
valuesChagesis a property of the directive NgModel, and the class FormControl(keep it mind that).
valuesChages是指令NgModel和类FormControl的属性(请记住这一点)。
The reactive approaches use the
ReactiveFormsModule import
(your.module.ts):
反应式方法使用
ReactiveFormsModule import
(your.module.ts):
import {ReactiveFormsModule} from '@angular/forms';
@NgModule({
...
imports: [
...
ReactiveFormsModule,
...
],
...
})
In this way you can use the [(formControl)]
property on your form controls (template.component.html).
通过这种方式,您可以[(formControl)]
在表单控件 (template.component.html) 上使用该属性。
<input type="text" class="form-control" id="searchBox"
required
[(formControl)]="searchBox"/>
Template-driven approached (your.module.ts):
接近模板驱动(your.module.ts):
import {FormsModule} from '@angular/forms';
@NgModule({
...
imports: [
...
FormsModule,
...
],
...
})
This approached has its own form control properties, ngModel(your.template.ts):
这个方法有自己的表单控件属性,ngModel(your.template.ts):
<input type="text" class="form-control" id="searchBox"
required
[(ngModel)]="searchBox"/>