ค้นหาเว็บไซต์

angular - Subscribe() ส่งค่ากลับ "complete:() => void; 'complete' ถูกประกาศที่นี่ นี่หมายความว่าอะไร?


ฉันกำลังติดตามบทเรียนสอน และผ่านการตรวจสอบและตรวจสอบซ้ำ ฉันมั่นใจ 100% ว่าโค้ดของฉันเหมือนกับที่อาจารย์ใช้ เรากำลังสร้างแอปหน้าเดียวแบบง่ายใน Angular ซึ่งโดยสมมติแล้วเกี่ยวข้องกับ Typescript

ฉันค่อนข้างมั่นใจว่าคลาสภายนอกทั้งหมดถูกเขียนอย่างถูกต้อง และ VS Code ไม่พบข้อผิดพลาดอื่นใดในโค้ดที่เขียน ยกเว้นสคริปต์ต่อไปนี้ในไฟล์ feed.component.ts แนวคิดคือการกำหนดแอตทริบิวต์ listPost (ประเภทอาร์เรย์และคลาส Post[]) ซึ่งรับรายการวัตถุโพสต์ที่อยู่ในที่อยู่ที่ระบุในคลาส PostService

เพื่อที่จะให้ชัดเจนมากขึ้น ปัญหาที่ฉันกำลังเผชิญอยู่คือในฟังก์ชัน findPosts() ซึ่งมันบอกว่ามีข้อผิดพลาดที่ชี้ว่า “complete() => void” (ซึ่งฉันไม่รู้ว่ามันหมายความว่าอะไร) สิ่งหนึ่งที่ทำให้ฉันกังวลคือสิ่งนี้ถูกเขียนเหมือนกับในไฟล์ของอาจารย์ทุกประการ ความแตกต่างเพียงอย่างเดียวคือเขาใช้ Typescript v. 3.9.2 ในขณะที่ฉันใช้ v. 4.3.2 ฉันสงสัยว่าสิ่งนี้อาจเป็นปัญหา เพราะจากที่ฉันค้นคว้ามา typescript มีปัญหาเยอะเมื่อแปลความหมายเวอร์ชันต่าง ๆ

import { Component, OnInit } from '@angular/core';
import { PostService } from '../service/post.service';
import { Post } from '../model/Post'

@Component({
  selector: 'app-feed',
  templateUrl: './feed.component.html',
  styleUrls: ['./feed.component.css']
})
export class FeedComponent implements OnInit {

  private listPost: Post[];

  constructor(private postService: PostService) {
    this.listPost = []
   }

  ngOnInit(): void {
    this.findPosts()
  }

  findPosts() {
    this.postService.getPosts()
                    .subscribe( 
                      (data: Post[]) => {this.listPost = data} );
  }

}

คำตอบ #1

ฉันเป็นผู้เขียนคำถามนี้และฉันจะตอบที่นี่ว่าฉันแก้ไขมันอย่างไร เพื่อให้สิ่งนี้อาจช่วยใครบางคนในอนาคต

โอเค ดังนั้น ฉันคิดว่านี่เกี่ยวข้องกับเวอร์ชันของ Typescript บางอย่าง ไม่รู้ว่าทำไม

ก่อนอื่น นี่คือวิธีที่โค้ดบทเรียนทำงานโดยใช้ Typescript 3.9:

export class FeedComponent implements OnInit {
listPost: Post[];

constructor(private postService) { }
ngOnInit(): void {
this.postService.getPosts().subscribe(
      (data: Post[]) => this.listPost = data )}}

โอเค ดังนั้น ความแตกต่างเพียงอย่างเดียวที่จำเป็นต้องนำไปใช้ในโค้ดนี้ ได้ถูกนำไปใช้อยู่แล้วเมื่อฉันสร้างคำถาม ซึ่งก็คืออันนี้:

export class FeedComponent implements OnInit {

  listPost: Post[];
  constructor(private postService: PostService) {
    this.listPost = []} // <--- THIS WAS INCLUDED
  ngOnInit(): void {
    this.postService.getPosts().subscribe(
      (data: Post[]) => this.listPost = data )}}

ดังนั้น ดูเหมือนว่าใน Typescript 4 ตอนนี้คุณจะต้องกำหนดค่าเริ่มต้นให้ตัวแปรใน constructor นั่นคือสาเหตุแรกของข้อผิดพลาด แต่ทำไมมันถึงยังคงคืนค่า Error อยู่? คำตอบอยู่ในไฟล์ post.services เมื่อฉันสร้างคำถาม ไฟล์ post.services ถูกเขียนแบบนี้:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})

export class PostService {

  constructor(private http: HttpClient) { }

  public getPosts() {
    return this.http.get('http://localhost:3000/posts')
  }
}

มันต้องถูกเขียนใหม่แบบนี้:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs'; // <--- THIS WAS INCLUDED
import { Post } from '../model/Post'; // <--- THIS WAS INCLUDED

@Injectable({
  providedIn: 'root'
})

export class PostService {

  constructor(private http: HttpClient) { }

  public getPosts(): Observable<Post[]> { // <--- THIS WAS MODIFIED
    return this.http.get<Post[]>('http://localhost:3000/posts')
  }
}

ฉันจริง ๆ ไม่รู้ว่าทำไมเรื่องนี้ถึงจำเป็น ฉันหาคำตอบโดยการลองผิดลองถูก ดูจากบริบทอื่น ๆ ที่คืนค่า error เหมือนกัน ดูเหมือนว่าการระบุประเภทของค่าที่คืนมาจากเมธอด get เป็น Observable กลายเป็นสิ่งที่จำเป็น ฉันเห็นว่าไวยากรณ์เป็นแบบนั้น ดังนั้นฉันจึงค้นพบว่าฉันก็ต้อง import โมดูล Post ของฉันและโมดูล Observable นี้เข้าไปในไฟล์บริการด้วย

สุดท้าย ในโมดูล Post ฉันยังต้องเริ่มต้นแอตทริบิวต์ JSON ในคอนสตรัคเตอร์ด้วย

คำตอบ #2

บางทีนี่อาจถูกต้อง

async findPosts() {
    await this.postService.getPosts()
        .subscribe((data: Post[]) => this.listPost = data);
}

บทความที่เกี่ยวข้อง