【问题标题】:How to make 1 call on backend endpoint instead of 2 on Header and Footer. Angular 10如何在后端端点上进行 1 次调用,而不是在页眉和页脚上进行 2 次调用。角 10
【发布时间】:2020-12-07 12:26:42
【问题描述】:

我有contact-info.service,它可以获取有关页眉和页脚组件的联系人信息。一切正常,但是对于这 1 个 json,BE 收到了 2 个呼叫而不是 1 个呼叫。我如何重构此代码以在后端仅调用 1 次。

所以,contact-info.service.ts:

export class ContactInfoService {
  private apiUrl: string;
  private endpoint = 'common/main-contact';

  constructor(private http: HttpClient) {
    this.apiUrl = environment.backendUrl;
  }

  getContactInformation(): Observable<ContactInfo> {
    return this.http.get<ContactInfo>(`${this.apiUrl}/${this.endpoint}`)
    .pipe(shareReplay(1));
  }
}

header.component.ts :

export class HeaderComponent implements OnInit {
  contactInfo$: Observable<ContactInfo>;

  constructor(private contactInfoService: ContactInfoService) { }

  ngOnInit(): void {
    this.contactInfo$ = this.contactInfoService.getContactInformation().pipe(shareReplay(1));
  }

}

footer.component.ts:

export class FooterComponent implements OnInit {
  currentDate = new Date();

  contactInfo$: Observable<ContactInfo>;

  constructor(private contactInfoService: ContactInfoService) {}

  ngOnInit() {
    this.contactInfo$ = this.contactInfoService.getContactInformation().pipe(shareReplay(1));
  }
}

【问题讨论】:

  • BE 是什么意思?
  • @FaizalHussain 我假设是“后端”,或者更确切地说是 api
  • 是的,就是后端
  • 实际上你是从页眉和页脚调用api。最好的方法是从页眉调用 API 并使用行为主题将其传递给页脚
  • @OlehZ 这可能会有所帮助:sharing data between angular components

标签: angular typescript api rest observable


【解决方案1】:

我遇到了你的问题...

请顺利检查此代码...

contact-info.service.ts:

import { map } from 'rxjs/operators';
import { Http} from '@angular/http';     //Updated...

  export class ContactInfoService {

  private apiUrl: string;
  public contactInfo = [];

  private endpoint = 'common/main-contact';

  constructor(private http: Http) {.        //Updated...
    this.apiUrl = environment.backendUrl;
  }

   //get request using operaters...

  getContactInformation() {
     return this.http.get('APIURL').pipe(map((response: any) =>response.json()));
   }

  getContactInformation(): Observable<ContactInfo> {
    return this.http.get<ContactInfo> (`${this.apiUrl}/${this.endpoint}`)
    .pipe(shareReplay(1));
  }

  setContactInfo(data) {
    this.contactInfo = data;
  }

  getContactInfo() {
    return this.contactInfo;
  }
}

header.component.ts :

 ngOnInit() {
     this.contactInfoService.getContactInformation().subscribe((res) => {
       this.contactInfoService.setContactInfo(res);
   }
 }

footer.component.ts:

ngOnInit() {
      let contactData = this.contactInfoService.getContactInfo()

      consolo.log(contactData)
   }
 }

现在您可以在整个项目中使用this.contactInfoService.getContactInfo() 作为contactInfo!

并且它只会向服务器发送一次请求

如果有任何帮助,请告诉我!

【讨论】:

  • 非常感谢,但是有了这个 - GET 请求不起作用并收到错误:ERR_NAME_NOT_RESOLVED
  • 但它以前在此对话开始时使用代码
  • 现在可以了吗?
  • ERROR TypeError: response.json is not a function
【解决方案2】:

您的服务应该如下所示 -

 export class ContactInfoService implements OnInit {
      private apiUrl: string;
      private endpoint = 'common/main-contact';
      private dataObs;
      constructor(private http: HttpClient) {
        this.apiUrl = environment.backendUrl;
        this.callContactInfo();
      }
     callContactInfo(){
       this.dataObs =  this.http.get<ContactInfo>(`${this.apiUrl}/${this.endpoint}`)
        .pipe(shareReplay(1));
    }
    
      getContactInformation(): Observable<ContactInfo> {
        return this.dataObs;
      }
    }

您可以直接在模板中使用getContactInformation(),而无需在页眉和页脚中使用pipe(shareReplay(1)),或者更好的方法是将getContactInformation() 返回的observable 存储在您的组件变量中,并通过异步管道在模板中使用它。

【讨论】:

  • 我尝试使用此代码,但在这种情况下,我再也看不到网络中的请求了。也许我不应该在模板中使用异步管道?
  • @OlehZ 我已经更新了我的答案。您无需在页眉或页脚中再次pipe(shareReplay(1))。要么直接订阅它,要么使用异步管道在模板中使用它。
  • 当组件 ngOnInit 中的 console.log(this.contactInfo$) 在这种情况下需要我未定义:(
  • 你的意思是什么?
  • 你的console.log(this.contactInfo$)
猜你喜欢
  • 2021-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-24
  • 2020-04-14
  • 2019-09-26
相关资源
最近更新 更多