【问题标题】:Angular2 Observable not binding correctlyAngular2 Observable 没有正确绑定
【发布时间】:2016-11-27 14:27:43
【问题描述】:

我正在努力通过 Angular2/TypeScript 实现搜索功能。

但是,我在将搜索项绑定到视图时遇到了一些问题。

我的组件是这样的:

import { Component } from '@angular/core';
import { SearchService } from '../services/search.service';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import "rxjs/add/operator/debounceTime";
import "rxjs/add/operator/distinctUntilChanged";
import 'rxjs/add/operator/switchMap';

@Component({
  selector: 'search',
  templateUrl: './app/views/search.component.html',
  providers: [SearchService]
})

export class SearchComponent {
  items: Observable<string[]>;
  errorMsg: string;

  private searchTermStream = new Subject<string>();

  searchConfluence(term : string) {
    // Send the search term into the Observable stream
    this.searchTermStream.next(term);
  }

  ngOnInit(): void {
    this.items = this.searchTermStream
      .debounceTime(300)
      .distinctUntilChanged()
      .switchMap(term => this.searchService.titleSearch(term));
  }

  constructor(private searchService: SearchService) {}
}

我的看法如下:

<h1>Search</h1>
<input #term (keyup)="searchConfluence(term.value)" />
<ul style="list-style: none">
  <li *ngFor="let item of items | async">
    {{item.title}}
  </li>
</ul>

我的搜索服务:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class SearchService {

  private searchUrl = URL_HERE;

  constructor(private http: Http) {}

  titleSearch(params: string): Observable<string[]> {
    let options = new RequestOptions({ headers: this.header});
    let requestString = `term=${params}`;
    return this.http.get(`${this.searchUrl}?${requestString}`, options)
      .map(this.getData)
      .catch(this.handleError);
  }

  private getData(resp: Response) {
    let body = resp.json();
    console.log(body.results);
    return body.results || [];
  }

  private handleError(error: Response | any) {
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    return Observable.throw(errMsg);
  }
}

服务器返回的响应如下:

 [Object, Object ... ]

每个Object 都是一个JSON 对象。这是我所期待的回应。

我检查了网络跟踪,并且 HTTP 请求正在触发到正确的位置,我也得到了返回结果(再次,所有通过网络跟踪查看)。我无法在我的视图中查看任何结果(列表根本没有出现)。

编辑:最后一次编辑,但我可能遗漏了一个关键细节;我的 Angular2 应用程序不在典型的浏览器中,但实际上包含在 ElectronJS 应用程序中。我不确定这是否有什么不同。

【问题讨论】:

  • 能否请您也添加SearchService服务代码?
  • 代码看起来很完美,它应该可以工作..可能是从 API 检索到的相关数据没有正确绑定..控制台有什么错误吗?
  • 请更新有问题的响应对象..
  • 不,控制台中没有错误,一切都只是空白。我不确定您所说的“响应对象”是什么意思。它是一个从服务器返回的 JSON 数组。
  • 是的,请添加..

标签: angular typescript observable


【解决方案1】:

折腾了一天,终于找到了这个问题的答案。

看起来 Electron 的 API 没有像网络浏览器那样快速更新,所以我遵循了 here 中的解决方案。

基本上我在我的search.component.ts 课堂上这样做:

ngOnInit(): void {
  this.searchTermStream
    .debounceTime(300)
    .distinctUntilChanged()
    .switchMap(term => this.searchService.titleSearch(term))
    .subscribe((result) => { 
      this.items = result;
      this.cdRef.detectChanges();
    });
  }

瞧,一切都在正确更新,我有一个很好的搜索结果列表:)。

【讨论】:

    猜你喜欢
    • 2017-01-28
    • 2019-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 2015-09-08
    • 1970-01-01
    相关资源
    最近更新 更多