自从我使用Ionic Framework(ionic-angular 3.9.2最新)构建Progressive Web Apps以来已经过了几个月。在此期间,我一直想知道ngOnInit
和ionViewWillLoad
之间的区别。
如果我没错,我相信ngOnInit
是Angular lifecycle hook并初始化指令和组件。 (设置指令/组件的输入属性。)
ionViewWillLoad
是Ionic 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接口?有什么区别?
答案 0 :(得分:5)
注意:对于V3,在提及生命周期方法时,我会交替使用术语“挂钩”和“事件”。
据我所知,ionViewWillLoad
不是最新版本的Ionic V3的生命周期挂钩之一。我很想知道您在其他生命周期事件中看到的错误。但是现在,我将这个答案的目标放在一些基本问题上:
1)Angular的ngOnInit
和Ionic的ionViewDidLoad
有什么区别?一个比另一个好吗?
足够有趣的是,在Angular的ngOnInit
和ngOnDestroy
生命周期挂钩与Ionic的ionViewDidLoad
和ionViewWillUnload
生命周期事件之间似乎有重叠的目的。仅在分别创建或删除页面时才调用它们,这可能不会像您想的那样频繁发生,因为Ionic倾向于缓存页面以获得更好的移动体验。
在V3的子/子组件中,唯一的选择是使用Angular生命周期挂钩。在V3的页面级组件(从NavController
推送/弹出的AKA组件)中,您可以互换使用它们,但是我只会选择其中一个,而不能同时选择两者,并且要保持一致。在Ionic V4中,他们通过删除ionViewDidLoad
和ionViewWillUnload
为您做出了选择。
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中的“后退”按钮或浏览器的“后退”按钮。
由于这种特殊处理,
ngOnInit
和ngOnDestroy
方法 当您通常认为他们应该这样做时,它可能不会触发。
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');
}
是不需要每次都触发的页面初始化任务的好钩子,因为在进入已经缓存的视图时不会触发它。