Angular if-then-else条件

时间:2017-05-20 18:38:04

标签: angular binding angular2-changedetection

问题

我正在尝试在搜索服务忙于检索和过滤结果时显示微调器。我认为*ngIf的更新的Angular语法除了if条件之外还允许你有一个else条件。但是每当我开始输入时,微调器都会正确显示,很快就会出现控制台中的错误,抱怨更改检测运行后值会发生变化。

  • 如何更正此问题?
  • 组件成员/属性的更改是否在视图中得到反映?为什么不改变检测而不是抱怨我的时间?

组件

@Component({
  selector: 'app-help-search',
  templateUrl: './help-search.component.html',
  styleUrls: ['./help-search.component.scss'],
  providers: [HelpSearchService]
})
export class HelpSearchComponent implements OnInit {
  searching: boolean;
  helpItems: Observable<HelpItem[]>;
  private searchTerms = new Subject<string>();

  constructor(
    private alertService: AppLevelAlertService,
    private helpSearchService: HelpSearchService,
    private router: Router) { }

  /**
   * Push a search term into the observable stream.
   */
  search(term: string): void {
    this.searching = true;
    this.searchTerms.next(term);
  }

  ngOnInit() {
    this.helpItems = this.searchTerms
      .debounceTime(300)
      .distinctUntilChanged()
      .switchMap(term => term
        ? this.helpSearchService.search(term)
        : Observable.of<HelpItem[]>([])
      )
      .catch(error => {
        this.alertService.errorOccurred.emit(new Error(error._body.error));
        return Observable.of<HelpItem[]>([]);
      })
      .finally(() => this.searching = false);
  }

  gotoHelpItem(helpItem: HelpItem): void {
    this.router.navigateByUrl(helpItem.url.toString());
  }

}

组件模板

<div id="search-component">
  <div class="form-group">
    <label for="search-box">Search for help topics: </label>
    <input type="text" #searchBox id="search-box" (keyup)="search(searchBox.value)" style="display: block; width: 100%; font-size: 20pt; height: 25pt" />
  </div>
  <div *ngIf="searching; then spinner else searchResults"></div>
  <ng-template #spinner>
    <span class="spinner spinner-lg">
      Loading...
    </span>
  </ng-template>
  <ng-template #searchResults>
    <div *ngFor="let helpItem of helpItems | async" (click)="gotoHelpItem(helpItem)" class="search-result">
      <app-help-item [helpItem]="helpItem"></app-help-item>
    </div>
  </ng-template>
</div>

enter image description here

我尝试了什么

我注意到在this.searching谓词中将false设置为.finally是导致此问题的原因。我尝试订阅this.helpItems并在next谓词设置this.searching中订阅false,而不是这种方法。这会在结果返回时正确删除微调器。但不幸的是,这仍然不起作用,因为for循环不占用微调器的位置。一旦结果回来,ng-templates都会消失。

1 个答案:

答案 0 :(得分:0)

我采用了不同的方法来解决这个问题。我没有使用新的number1.setText("0") if-then-else条件来决定渲染哪个*ngIf,而是选择覆盖微调器并使用css来控制其可见性。以下是改进后的方法,对我来说效果很好:

组件

ng-template

模板

import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { Router } from '@angular/router';
import { Observable, Subject } from 'rxjs/Rx';

import { AppLevelAlertService } from '../alerts/app-level-alert.service';
import { HelpItem } from '../help-item';
import { HelpSearchService } from '../help-search.service';

@Component({
  selector: 'app-help-search',
  templateUrl: './help-search.component.html',
  styleUrls: ['./help-search.component.scss'],
  providers: [HelpSearchService]
})
export class HelpSearchComponent implements OnInit {
  @ViewChild('overlay') overlay: ElementRef;

  searching: Subject<boolean> = new Subject<boolean>();
  helpItems: Observable<HelpItem[]>;

  private searchTerms = new Subject<string>();

  constructor(
    private alertService: AppLevelAlertService,
    private helpSearchService: HelpSearchService) {
    this.searching.subscribe(searching => this.overlay.nativeElement.style.display = searching ? 'block' : 'none');
  }

  /**
   * Push a search term into the observable stream.
   */
  search(term: string): void {
    this.searching.next(true);
    this.searchTerms.next(term);
  }

  ngOnInit() {
    this.helpItems = this.searchTerms
      .debounceTime(300)
      .distinctUntilChanged()
      .switchMap(term => {
        const results = term
          ? this.helpSearchService.search(term)
          : Observable.of<HelpItem[]>([]);
        return results;
      })
      .catch(error => {
        this.alertService.errorOccurred.emit(new Error(error._body.error));
        return Observable.of<HelpItem[]>([]);
      });
    this.helpItems.subscribe(thing => this.searching.next(false));
  }

}

定型

<div id="search-component">
  <div class="form-group">
    <label for="search-box">Search: </label>
    <input type="text" #searchBox id="search-box" (keyup)="search(searchBox.value)" />
  </div>
  <div #overlay id="overlay">
    <span class="spinner spinner-lg">
      Loading...
    </span>
  </div>
  <app-help-item *ngFor="let helpItem of helpItems | async" [helpItem]="helpItem"></app-help-item>
</div>