Angular2表单控件valueChanges可观察完成从未调用

时间:2016-05-30 18:17:33

标签: javascript typescript angular rxjs observable

我正在尝试在搜索栏中显示一个简单的加载器,同时进行搜索。我计划在valueChanges observable的subscribe回调中将一个变量从我的表单控件设置为值" loading",并在完整的回调中将其设置为空字符串。但是,永远不会调用完整的回调。

我还尝试在observable上添加一个回调函数,但它也永远不会被调用。

我的代码:

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");
            });
}

3 个答案:

答案 0 :(得分:5)

这是正常的,因为观察者永远不会完成。 valueChanges可让您从搜索框中获得价值。实际上,您希望在搜索操作完成时收到通知。

所以我会尝试类似的东西,假设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);
              });
}

有关flatMap运算符的使用,请参阅此文章:

答案 1 :(得分:1)

我发现我正在尝试错误的做法。相反,我意识到我的观察结果中有debounceTime,因此我在输入控件上注册了keyup事件,并在其中将loadingClass的值设置为"loading",并且在我的订阅中,我将值设置回空字符串。

答案 2 :(得分:0)

我希望这可以让一些人更好地理解Angular2 Forms。 Angular有两种不同的构建形式的方法(Reactive和Template形式)。不知道这可能会导致你的应用程序混乱。

valuesChages 是指令 NgModel 的属性,类 FormControl (请注意)。

  

反应方法使用 ReactiveFormsModule import   (your.module.ts):

import {ReactiveFormsModule} from '@angular/forms';

@NgModule({
  ...
  imports: [
    ...
    ReactiveFormsModule,
    ...
  ],
  ...
})

通过这种方式,您可以在表单控件(template.component.html)上使用[(formControl)]属性。

<input type="text" class="form-control" id="searchBox"
       required
       [(formControl)]="searchBox"/> 
  

模板驱动接近(your.module.ts):

import {FormsModule} from '@angular/forms';

    @NgModule({
      ...
      imports: [
        ...
        FormsModule,
        ...
      ],
      ...
    })

此方法有自己的表单控件属性, ngModel (your.template.ts):

<input type="text" class="form-control" id="searchBox"
       required
       [(ngModel)]="searchBox"/>