【问题标题】:Correlation between ngOnInit and ionViewWillLoad lifecycle hook/eventngOnInit 和 ionViewWillLoad 生命周期钩子/事件之间的相关性
【发布时间】:2018-08-16 15:37:31
【问题描述】:

自从我使用 Ionic Framework (ionic-angular 3.9.2 latest) 构建渐进式 Web 应用程序以来已经有几个月了。同时,我一直想知道ngOnInitionViewWillLoad 之间的区别。

如果我没记错的话,我相信ngOnInit 是一个Angular lifecycle hook,它会初始化指令和组件。 (设置指令/组件的输入属性。)

ionViewWillLoad 是一个Ionic navigation lifecycle event,它似乎在ionViewDidLoad (一切都已加载) 事件被触发之前被执行。看起来ionViewWillLoad事件还没有添加到NavController,文档也没有更新。

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

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

我不知道为什么,但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接口更好?有什么区别?

【问题讨论】:

    标签: angular typescript ionic-framework


    【解决方案1】:

    注意:对于 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 有什么区别?一个比另一个更好吗?

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

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

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

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

    对于 Ionic V4 (Angular)

    生命周期事件在 V4 中更加直接。 Ionic 生命周期事件的数量只有一半,并且它们在功能上与我在 v3 中提到的 Angular 生命周期事件没有重叠。 usage of Angular and Ionic lifecycle events 周围的每个和 actual guidance 都有很好的解释

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

    页面只有在“弹出”时才会从 DOM 中删除,例如,通过按下 UI 中的后退按钮或浏览器的后退按钮。

    由于这种特殊处理,ngOnInitngOnDestroy 方法 可能不会在您通常认为应该触发的时候触发。

    ngOnInit 只会在每次新创建页面时触发,但不会 当导航回页面时。例如,在每个之间导航 选项卡界面中的页面只会调用每个页面的ngOnInit 方法 一次,但不会在随后的访问中。 ngOnDestroy 只会在一个 页面“弹出”。

    【讨论】:

    • 虽然,我不再使用 Ionic 框架,但感谢您的澄清以帮助其他观众。
    【解决方案2】:

    在 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');
      }
    

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

    【讨论】:

      猜你喜欢
      • 2020-11-05
      • 1970-01-01
      • 2017-03-07
      • 1970-01-01
      • 2017-12-06
      • 2016-07-18
      • 2020-01-15
      • 2017-11-22
      • 1970-01-01
      相关资源
      最近更新 更多