Angular 在组件之间共享动态创建的可观察对象

Angular 在组件之间共享动态创建的可观察对象,angular,rxjs,observable,Angular,Rxjs,Observable,我有两个同级组件,它们需要访问在基于用户输入可观察的服务中动态创建的可观察对象中检索的数据。我正在努力理解如何让搜索列表组件监听搜索组件创建的可观察对象。我是否应将服务确认的最后一次搜索可观察到的内容存储为搜索服务中的另一个可观察内容,我是否应将搜索可观察内容存储在搜索组件中并通过ref进行访问,还是应在观察者在搜索组件中完成后发出数据 search.service.ts export interface SearchApi { data: string[] } export class S

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

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);
  }
}
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}`);
    });
  } 
}
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}`);
    });
    */
  } 
}

其中一个选项是将
searchTerm$
Observable向上移动一个级别,到封装它们的组件。然后你可以把它作为@Input传递给它们,它会监听它们内部的更新。如果需要更新它,还可以传递@Output函数来更新父组件中的可观察值

另一个选项是将此可观察对象添加到服务中,并将服务注入两个组件中。这也会起作用


这是两种方法中的一种。

只需使用一个主题来共享状态,并将“加载状态”操作与“接收状态”操作分离


我应该直接调用this.loading.next(true)/this.loading.next(false)来更新,对吗?
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);
  }
}
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
  } 
}
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}`);
    });
  } 
}