ngOnInit和ionViewWillLoad生命周期钩子/事件

时间:2018-03-08 10:09:55

标签: angular typescript ionic-framework

自从我使用Ionic Framework(ionic-angular 3.9.2最新)构建Progressive Web Apps以来已经过了几个月。在此期间,我一直想知道ngOnInitionViewWillLoad之间的区别。

如果我没错,我相信ngOnInitAngular lifecycle hook并初始化指令和组件。 (设置指令/组件的输入属性。)

ionViewWillLoadIonic navigation lifecycle event,它似乎在ionViewDidLoad 之前执行(所有内容都已加载)事件被触发。看起来ionViewWillLoad事件尚未添加到NavController,文档还没有更新。

据我所知,构造函数由JavaScript引擎调用,应该避免使用它进行复杂的初始化。 details: why you should avoid complex constructor logic

出于这个原因,我在Ionic设置输入属性后使用ionViewWillLoad来设置组件。

我不确定原因,但ionViewWillLoad是唯一一个没有出错的事件。

export class UsernamePage {
  usernameControl: FormControl;

  constructor(private userService: UserServiceProvider){ }

  // No errors
  ionViewWillLoad() { this.createUsernameForm(); }

  // Errors
  ionViewWillEnter() { this.createUsernameForm(); }
  ionViewDidEnter() { this.createUsernameForm(); }
  ionViewDidLoad() { this.createUsernameForm(); }

  createUsernameForm() {
    this.usernameControl = new FormControl('',
    {
      validators: [Validators.required, Validators.minLength(4)],
      asyncValidators: CustomValidator.username(this.userService)
    });
  }
}

我应该坚持使用ionViewWillLoad吗?或者更好地实现OnInit接口?有什么区别?

2 个答案:

答案 0 :(得分:5)

注意:对于V3,在提及生命周期方法时,我会交替使用术语“挂钩”和“事件”。

据我所知,ionViewWillLoad不是最新版本的Ionic V3的生命周期挂钩之一。我很想知道您在其他生命周期事件中看到的错误。但是现在,我将这个答案的目标放在一些基本问题上:

1)Angular的ngOnInit和Ionic的ionViewDidLoad有什么区别?一个比另一个好吗?

足够有趣的是,在Angular的ngOnInitngOnDestroy生命周期挂钩与Ionic的ionViewDidLoadionViewWillUnload生命周期事件之间似乎有重叠的目的。仅在分别创建或删除页面时才调用它们,这可能不会像您想的那样频繁发生,因为Ionic倾向于缓存页面以获得更好的移动体验。

在V3的子/子组件中,唯一的选择是使用Angular生命周期挂钩。在V3的页面级组件(从NavController推送/弹出的AKA组件)中,您可以互换使用它们,但是我只会选择其中一个,而不能同时选择两者,并且要保持一致。在Ionic V4中,他们通过删除ionViewDidLoadionViewWillUnload为您做出了选择。

2)Angular的ngOnInit和Ionic的ionViewWillEnter有什么区别?一个比另一个好吗?

首先,这些问题仅适用于页面级组件,因为Ionic Lifecycle事件只能在页面级组件(V3 documentation)中使用。子/子组件对离子生命周期事件一无所知,因为它们没有被NavController推动/弹出(这可能是您看到错误的原因吗?)。

这两个特定事件之间的主要区别在于它们触发的顺序和触发频率。创建页面级组件时,ngOnInit将在ionViewWillEnter之前触发。但是,除非将页面从导航堆栈(V3 documentation)中弹出,否则它们不一定会被破坏(因此以后将不会重新创建)。

  

默认情况下,如果页面离开导航堆栈但仍位于导航堆栈中(例如,push()上的退出页面),则将页面缓存并留在DOM中。从导航堆栈(在pop()setRoot()上删除它们时,它们会被销毁。

我不会说一个比另一个更好。您可以同时实现。请注意,ngOnInit可能不会像您期望的那样频繁/一致地触发。每当页面即将进入并变为活动页面时,ionViewWillEnter就会触发。

对于Ionic V4(角度)

生命周期事件在V4中更为简单。 Ionic生命周期事件的数量是一半,并且它们在功能上与Angular生命周期事件没有重叠,就像我在v3中提到的那样。 actual guidance

中的每个和usage of Angular and Ionic lifecycle events都有很好的解释

主要内容相似(我相信适用于V3)。

  

仅当页面“弹出”时才将其从DOM中删除,例如,通过按下UI中的“后退”按钮或浏览器的“后退”按钮。

     

由于这种特殊处理,ngOnInitngOnDestroy方法   当您通常认为他们应该这样做时,它可能不会触发。

     

ngOnInit仅在每次新创建页面时触发,但不会   导航回该页面时。例如,在每个   标签界面中的页面只会调用每个页面的ngOnInit方法   一次,但以后不会访问。 ngOnDestroy仅在   页面“弹出”。

答案 1 :(得分:1)

在Ionic 3中,您应该使用

  ionViewWillEnter () {
    console.log('fired every time you enter the view');
  }

它应该用于每次要执行的任务,例如访问可能已更改的数据或更新表。

ionViewDidLoad () {
    console.log('not fired on entering a view that is already cached');
  }

是不需要每次都触发的页面初始化任务的好钩子,因为在进入已经缓存的视图时不会触发它。