【问题标题】:Getting data from HTTP request to late in the template从 HTTP 请求获取数据到模板的后期
【发布时间】:2019-06-27 13:28:49
【问题描述】:

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

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

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

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

感谢您的帮助

带有 Subject 和 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) 与主题调用

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="data !== null &amp;&amp; data !== undefined"
  • 你为什么不订阅你的服务?
  • @kebbaben 不,我还没试过
  • @Ari Waisberg 因为我是这样从课程中学到的 :( 也许还有其他方法,但我不知道该怎么做
  • @kebbaben 你的解决方案也很好用!!!太感谢你了!!! :)

标签: angular ionic-framework behaviorsubject subject


【解决方案1】:

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

*ngIf=="data"

您还可以使用 *ngIf 来检查另一个 div 的长度是否大于零,以通知数据已经到达这里但没有记录...

【讨论】:

    【解决方案2】:

    首先你必须在 ngOninit 中调用服务方法而不是在构造函数中获取数据 看看这个链接 [Difference between Constructor and ngOnInit

    那么在将所有数据显示到模板之前,您必须使用 *ngIf 确保数据已经存在

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

    【讨论】:

      【解决方案3】:

      我注意到您的代码和逻辑中有几个问题。

      1. ngOnInit 通常用于所有初始化/声明。最好避免将逻辑放在构造函数中。构造函数应该只用于初始化类成员,而不应该做实际的“工作”。所以我建议你将你的逻辑从构造函数移到你的ngOnInit()

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

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

      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
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-03-04
        • 2021-06-04
        • 1970-01-01
        • 1970-01-01
        • 2022-06-11
        • 2018-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多