从 HTTP 请求获取数据到模板的后期

Getting data from HTTP request to late in the template

我有一个为主题和行为主题创建 http 请求的服务。然后我将数据从服务获取到 page.ts(在构造函数上)以在模板中显示它。

我做的代码运行良好,但问题是模板 "yelling" 来自主题的数据尚未到达。所以如果我想用它来初始化 FORM 控件或显示数组中的数据,它会给我错误。

PS: 我尝试将主题设置为 behaviorSubject,我遇到了同样的问题。 :( 我确定我在做一个概念错误。

有人知道如何在显示模板之前获取数据吗?

感谢您的帮助

带有主题和行为主题的服务代码:

const INTI_DATA = [];

@Injectable({
  providedIn: 'root'
})
export class FormStorageService {
  dbSubject = new Subject<any[]>();
  dbBSubject = new BehaviorSubject(INTI_DATA);
  data$: Observable<any> = this.dbBSubject.asObservable();

  private _URL: any = '../assets/DB-Test/data.json';


  private dbData: any[] = [];

  constructor(private http: HttpClient) {}


  getDBDataBehavior() {
    this.http.get<any[]>(this._URL).subscribe((response: any[]) => {
      const value = response['DB_DATA'];
      this.dbBSubject.next(value);
    }, error => {
      console.log('Error : ', error);
      alert(error.message);
    });
  }

  getDBData() {
    this.http.get<any[]>(this._URL).subscribe((response: any[]) => {
      const value = response['DB_DATA'];
      this.dbSubject.next(value);
    }, error => {
      console.log('Error : ', error);
      alert(error.message);
    });
  }
}

Page.TS (Form2Page) with Subject call

export class Form2Page implements OnInit, OnDestroy {
  obsSubscription: Subscription;
  public dbData: DataModel[] = [];

  itemsForm: FormGroup;

  constructor(private storageService: FormStorageService) {
    // Get data from DB
    this.storageService.getDBData();
    this.obsSubscription = this.storageService.dbSubject.subscribe(
      (value: any[]) => {
        this.dbData = value;
        console.log('Value in FORM2 : ', value);
        console.log('DB Data in FORM2 in subscribe : ', this.dbData);
      },
      error => {
        console.log('erreur', error);
      }
    );
    console.log('DB Data DB Data in FORM2 : ', this.dbData);
  }

  ngOnInit() {
    console.log('DB Data in FORM2 in ngOnInit : ', this.dbData);
  }

  ngOnDestroy() {
    this.obsSubscription.unsubscribe();
  }
}

控制台结果过一会可以看到dbData得到了一些数据

DB Data DB Data in FORM2 :  []
form2.page.ts:46 DB Data in FORM2 in ngOnInit :  []
form2.page.ts:29 Value in FORM2 :  {ITEMS: Array(1)}
form2.page.ts:30 DB Data in FORM2 in subscribe :  {ITEMS: Array(1)}

Page.TS (Form3Page) 调用 BehaviorSubject

export class Form3Page implements OnInit {
  obsBSubject$ = this.formStorage.data$;
  public dbData: any[] = [];

  constructor(private formStorage: FormStorageService) { 
    this.formStorage.getDBDataBehavior();
    this.obsBSubject$.subscribe(
      (value: any[]) => {
        this.dbData = value;
        console.log('Value in FORM3 : ', value);
        console.log('DB Data in FORM3 in subscribe : ', this.dbData);
      },
      error => {
        console.log('erreur', error);
      }
    );
    console.log('DB Data in FORM3 : ', this.dbData);
  }


  ngOnInit() {
    console.log('DB Data in FORM3 in ngOnInit : ', this.dbData);
  }

}

控制台结果过一会可以看到dbData得到了一些数据

Value in FORM3 :  []
form3.page.ts:19 DB Data in FORM3 in subscribe :  []
form3.page.ts:25 DB Data in FORM3 :  []
form3.page.ts:30 DB Data in FORM3 in ngOnInit :  []

form3.page.ts:18 Value in FORM3 :  {ITEMS: Array(1)}
form3.page.ts:19 DB Data in FORM3 in subscribe :  {ITEMS: Array(1)}

您可以使用 *ngIf 来验证数据是否已经到达前端

*ngIf=="data"

您还可以使用另一个 div 和 *ngIf 检查长度是否大于零,以告知数据已经到达此处但没有记录...

首先你必须在 ngOninit 中而不是在构造函数中调用服务方法来获取数据 看看这个 link [

然后在将所有数据显示到模板之前,您必须使用 *ngIf

确保数据已经存在

如果您不关心性能,请使用 setTimeOut 函数解决解决方案,但我个人不喜欢这个解决方案...

我注意到您的代码和逻辑中存在一些问题。

  1. ngOnInit通常用于所有initialization/declaration。最好避免将逻辑放在构造函数中。构造函数应该只用于初始化 class 成员而不应该做实际的 "work"。所以我建议您将逻辑从构造函数移至 ngOnInit()

  2. 您没有在控制台中看到数据,因为流程是异步的。因此,您的日志会在 this.dbdata 实际收到值之前显示在控制台中。

  3. 由于第 2 点中提到的原因,如果您尝试在与控制台相同的行上创建表单,您将收到错误消息,因为没有数据。相反,您应该在订阅方法中收到数据后创建表单。

Page.TS (Form3Page) 调用 BehaviorSubject

export class Form3Page implements OnInit {
  obsBSubject$ = this.formStorage.data$;
  public dbData: any[] = [];

  constructor(
    private formStorage: FormStorageService
  ) { }

  ngOnInit() {
    this.formStorage.getDBDataBehavior();
    this.obsBSubject$.subscribe(
      (value: any[]) => {
        this.dbData = value;
        this.createForm();
        ...
      },
      error => {
        console.log('erreur', error);
      }
    );
  }

  createForm() {
    // Create form here
  }
}