angular - 在组件之间共享动态创建的 observable

标签 angular rxjs observable

我有两个同级组件,它们需要访问在可观察对象中检索的数据,该可观察对象是在基于用户输入可观察对象的服务中动态创建的。我正在努力理解如何让 search-list 组件监听由 search 组件创建的可观察对象。我是否应该将服务创建的最后一个搜索可观察值存储为搜索服务中的另一个可观察值,是否应该将搜索可观察值存储在 search 组件中并通过引用进行访问,还是应该在搜索后发出数据观察者在 search 组件中完成?

search.service.ts

export interface SearchApi {
 data: string[]
}

export class SearchService {
  loading: EventEmitter<boolean> = new EventEmitter();

  constructor(private httpClient: HttpClient) {

  }

  search(terms: Observable<string>){
     return terms.pipe(debounceTime(400))
     .pipe(distinctUntilChanged())
     .pipe(switchMap(term => {
        this.loading.emit(true);
        return this.searchEntries(term);
     }))
     .pipe((data) => {
        this.loading.emit(false);
        return data;
     });
  }

  searchEntries(term){
    return this.httpClient.post<SearchApi>(this.baseUrl,term);
  }
}

search.component.ts

import { Subject, Observable } from 'rxjs';

export class SearchComponent implements OnInit {

  searchTerm$ = new Subject<string>();

  constructor(private searchService: SearchService) {
    searchService.loading.subscribe(isLoading => {
      console.log(`Is loading: ${isLoading}`);
    });

    searchService.search(this.searchTerm$).subscribe(results => {
      console.log(`Search results ${results}`);
    });
  } 
}

search-list.component.ts

export class SearchListComponent implements OnInit {

  constructor(private searchService: SearchService) {
    searchService.loading.subscribe(isLoading => {
      console.log(`Is loading: ${isLoading}`);
    });

    /* Not sure how I would subscribe to observable that search.service.ts created */
    /*
    searchService.search().subscribe(results => {
      console.log(`Search results ${results}`);
    });
    */
  } 
}

最佳答案

只需使用主题来共享状态并将“加载状态”操作与“接收状态”操作分开。

export class SearchService {
  private loading: Subject<boolean> = new Subject(); // use subjects, keep them private
  loading$: Observable<boolean> = this.loading.asObservable(); // public observable


  private searchResults = new BehaviorSubject(null);  // BehaviorSubjects solve timing problems
  searchResults$ = this.searchResults.asObservable(); 

  constructor(private httpClient: HttpClient) {

  }

  search(terms: Observable<string>){
     return terms.pipe(
         debounceTime(400), // cleaner syntax / less pipes
         distinctUntilChanged(),
         tap(v => this.loading.next(true)), // subjectsuse next, use tap for side effects
         switchMap(term => this.searchEntries(term)),
         tap(v => this.loading.next(false)) // use tap for side effects
     ).subscribe(this.searchResults); // send it to the subject
  }

  searchEntries(term){
    return this.httpClient.post<SearchApi>(this.baseUrl,term);
  }
}

然后在您的组件中,您订阅 searchResults$ 并在想要填充搜索结果时调用 search() 。

搜索.component.ts

import { Subject, Observable } from 'rxjs';

export class SearchComponent implements OnInit {

  searchTerm$ = new Subject<string>();

  constructor(private searchService: SearchService) {
    searchService.loading$.subscribe(isLoading => {
      console.log(`Is loading: ${isLoading}`);
    });

    searchService.search(this.searchTerm$); // call the state load action
  } 
}

搜索列表.component.ts

export class SearchListComponent implements OnInit {

  constructor(private searchService: SearchService) {
    searchService.loading$.subscribe(isLoading => {
      console.log(`Is loading: ${isLoading}`);
    });

    searchService.searchResults$.subscribe(results => { // receive state here
      console.log(`Search results ${results}`);
    });
  } 
}

关于angular - 在组件之间共享动态创建的 observable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54915871/

相关文章:

pagination - RxJs可观察到的分页

scala - 连接数百个 RxScala Observables(每个都有数百万个事件要发出)的有效方法?

angular - Uncaught TypeError : r. existsSync 不是 Angular 6 和 Electron 桌面应用程序中的函数

angular - 从 Ngx-Datatable 获取当前显示计数

javascript - 类型错误 : Cannot read property 'maps' of undefined (Google maps places autocomplete Angular 2)

javascript - 带延迟的递归可观测方法

javascript - 类型 'mergeMap' 上不存在属性 'Observable<any>'

angular - Angular 中的主题在 500 内部错误后停止工作

javascript - 单个值的 Observable 与 Promise

java - 如何在 rxJava 中订阅不同的线程池