写作文章的当下,已经是Ionic 4和5的时代,但近期有个Ionic 3的项目需要优化,而之前对Ionic 和Angular都没有接触,入门过程中遇到一些概念上的疑惑,这里做些总结。
Angular Module
对比过Angular 和Ionic 会发现,两者的CLI 工具,在生成代码方面,有一点差异:
ng g module shop
ng g c shop/index
ng g c shop/cart
ng g c shop/checkout
ng g c shop/confirm
通过这组命令,Angular 可以生成一个module,并在这个module 下生成多个component 并包含进module。
@NgModule({
imports: [
CommonModule
],
declarations: [IndexComponent, CheckoutComponent, CartComponent, ConfirmComponent]
})
export class ShopModule { }
但是在Ionic 中,在生成代码时,类型中并没有module,但是却多了一个page
的概念。
ionic generate [] [] [options]
type ..................... The type of generator (e.g. component, directive,
page, pipe, provider, tabs)
Ionic Page
在Ionic 中page
有两层概念,首先它是一个component,其次它也可以是一个module。初次接触可能会有点晕,我们看下例证。
第一步
ionic generate page cart --no-module
先不去管尾部参数的含义,这行命令,创建了一个component:CartPage
@Component({
selector: 'page-cart',
templateUrl: 'cart-page.html',
})
export class CartPage {
constructor(public navCtrl: NavController, public navParams: NavParams) {
}
}
这里体现了page
的第一层概念,它是一个component。
第二步
ionic generate page shop
这行命令,创建了一个component:ShopPage
,以及聚合了这个component 的module。
// shop.ts
@IonicPage
@Component({
selector: 'page-shop',
templateUrl: 'shop-page.html',
})
export class ShopPage {
constructor(public navCtrl: NavController, public navParams: NavParams) {
}
}
// shop.module.ts
@NgModule({
declarations: [
ShopPage
],
imports: [
IonicPageModule.forChild(ShopPage),
]
})
export class ShopPage {}
这里体现了page
的第二层概念。
注意这里,在component 定义的上方,多了一个
@IonicPage
的注解。Ionic 框架会对它有特殊的处理,已知的部分是,如果component 上有这个注解,但Ionic 运行时如果没有找到相同名称的module,会报错。
这里是个人觉得Ionic 设计原语中不大一致的地方,通过ionic g page --no-module
创建的page 却不是IonicPage
,直观的体现是,生成的component 上方没有这个注解 。(仅仅站在框架使用者的角度)
Ionic 中如何把多个页面“聚合”在一个module 中
在开始的例子中,Angular CLI 生成的一组文件,实现了一个效果,在shop 这个module 中,包含了index, cart, checkout, confirm 四个页面。
module 是Angular 运行时,控制资源(js)加载的单位,我们可以整体控制一个module 是预加载还是懒加载,从而实现不同场景下的优化策略。
Ionic 运行时,对module 默认是懒加载的。
如果我们需要在Ionic 中,对shop 的四个页面,实现整体预加载,那么首先要把这些页面聚合到一个module 中,该怎么做呢?
Ionic module 预加载的设置,不在此文讲述。
Ionic CLI 在生成代码时,并没有像Angular CLI 那样,对这个需求提供直接支持。因为如前文提到,在CLI 提供的语义中,没有module 这个概念。
但实际生成的代码中module 是存在的,所以我们可以自己动手。
第一步
ionic generate page cart --no-module
ionic generate page checkout --no-module
ionic generate page confirm --no-module
第二步
修改shop module 定义
// shop.module.ts
@NgModule({
declarations: [
ShopPage,
CartPage,
CheckoutPage,
ConfirmPage
],
imports: [
IonicPageModule.forChild(ShopPage),
],
entryComponents: [
CartPage,
CheckoutPage,
ConfirmPage
]
})
回顾
通过对page 和module 的概念区分,以及对比Angular 和 Ionic CLI 在生成代码环节的差异,我们可以了解到,如何在Ionic 中,如何手动组织module,来灵活的满足运行时灵活的资源加载需求。