【问题标题】:how can i listen to a method, when it is called or executed in Angular当在 Angular 中调用或执行方法时,我如何收听方法
【发布时间】:2021-09-28 17:05:47
【问题描述】:

我正在尝试像这样在 Angular 中将数据从一个组件发送到另一个组件

onSubmit(form: NgForm){
  this.newsService.searchNews(form.value.query).subscribe((res:any) => {
    this.newsService.searchedNews.next(res.articles);      
  });
}

我正在将搜索到的新闻从我的搜索组件发送到我的主组件,如果我在我的主组件中订阅 ngOnInit 中的主题,则数据将为 null,因为尚未调用该方法或用户没有搜索任何东西,所以我的问题是,有没有办法在我的HomeComponent 中调用或执行此方法(SearchComponent)时,这就是服务

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import { Article } from '../models/article';

@Injectable({
  providedIn: 'root'
})
export class NewsService {

  searchedNews = new BehaviorSubject<any>('');

  constructor(private http: HttpClient) { }

  getHeadlines() {
    return this.http.get(`https://newsapi.org/v2/top-headlines?country=us&apiKey=${this.newsApiKey}`);
  }

  searchNews(query: string) {
    return this.http.get(`https://newsapi.org/v2/everything?q=${query}&apiKey=${this.newsApiKey}`)
  } 
}

【问题讨论】:

  • 你的home组件和父子搜索组件有什么关系吗?
  • 不,它们无关
  • 你能再解释一下你的问题吗,你的意思是数据为空并且你已经在家庭组件中收听,那么你要求什么?
  • 当然,一旦用户搜索任何内容,搜索的数据就会存储在我的搜索组件中,我如何在我的主组件中发送这些数据,我在考虑 ngOnint 但主组件之前已经呈现用户搜索任何东西,希望我足够清楚
  • 你在使用行为主题吗?可以添加代码 sn -p 吗?

标签: angular typescript rxjs


【解决方案1】:

一般而言,您的服务对象不应公开。使用将调用 next 的 set 方法,并以主题为源创建一个新的 observable。

对于迟到的订阅者,可以使用不同类型的主题。这意味着您的 observable 将在订阅时发出最新的值。例如,您可以使用 ReplaySubject、BehaviorSubject 或 AsyncSubject(它应该在开始发射之前完成)。您还可以使用 ShareReplay 运算符。

最后但并非最不重要。记得取消订阅你的 observable 以避免内存泄漏或其他坏东西。您可以使用异步管道直接在模板中执行此操作。例如obs$ | async。你也可以在组件中通过在 ngOnDestroy 中取消订阅来销毁它。

这是一个例子。在这种情况下,null 是默认值,但您可以更改它。组件可以订阅searchedNews$,迟到的订阅者将获得最后发出的值。如果没有发出任何内容,观察者将收到一个空值。

@Injectable()
export class NewsService {

  private _searchedNews$ = new BehaviorSubject(null);
  searchedNews$ = this._searchedNews$.asObservable(); 

  sendArticle(article: Article){
    this._searchedNews$.next(article);
  }

}

在组件中是:

@Component({
  selector: 'homecomponent',
  template: `<h1>{{newsobs$ | async}}</h1>`,
})
export class HomeComponent {
  newsobs$ = this.newsService.searchedNews$;

  constructor(private newsService: NewsService) {}
}

@Component({
  selector: 'searchComponent',
})
export class Searchomponent implements OnInit {
  constructor(private newsService: NewsService) {}

  ngOnInit(): void {
    this.newsService.sendArticle({} as Article);
  }
}

更新: 在我第一次回答后,您可以看到您已经更新了您的问题。也许你可以做到这一点。您不必取消订阅 HTTP 调用,因为它们会自动完成。

import { BehaviorSubject } from "rxjs";

@Injectable({
  providedIn: 'root'
})
export class NewsService {

  private _searchedNews$ = new BehaviorSubject<any>('');
  searchedNews$ = this._searchedNews$.asObservable();

  constructor(private http: HttpClient) { }

  getHeadlines() {
    return this.http.get(`https://newsapi.org/v2/top-headlines?country=us&apiKey=${this.newsApiKey}`);
  }

  searchNews(query: string) {
    return this.http
      .get(`https://newsapi.org/v2/everything?q=${query}&apiKey=${this.newsApiKey}`)
      .subscribe(x => this.searchedNews$.next(x))
  } 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-09
    • 2018-08-26
    • 2012-10-01
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多