ionic2是一款比較優(yōu)秀的基于angular的移動(dòng)端框架,其源碼蘊(yùn)含了豐富的設(shè)計(jì)思想,我們本文講一起學(xué)習(xí)ionic如何如何運(yùn)行我們自己寫(xiě)的業(yè)務(wù)代碼的。下面我將在angular工程的基礎(chǔ)上進(jìn)行ionic框架的搭建。今天我們將從ionic的ion-app標(biāo)簽開(kāi)始進(jìn)行學(xué)習(xí),以實(shí)現(xiàn)我們最簡(jiǎn)化的ionic程序.
之前我們?cè)趯?xiě)ionic,曾在app.module.ts中,使用如下的代碼:
@NgModule({
declarations: [... ],
imports: [
IonicModule.forRoot(...)
],
bootstrap: [IonicApp],
entryComponents: [...],
providers: [...]
})
想必很多人沒(méi)有關(guān)心過(guò)bootstrap: [IonicApp],我們也不會(huì)去隨便更改這一句代碼。如果是標(biāo)準(zhǔn)的ionic程序,修改這條語(yǔ)句,會(huì)報(bào)錯(cuò)。
這一句話在ionic包的app-root.ts中定義,在這里我們就不去解釋源碼了。
下面我對(duì)原來(lái)的app-root.ts進(jìn)行了簡(jiǎn)化,大概的模樣如下:
import { Component,OnInit,ViewChild,ViewContainerRef,
Inject,
ElementRef,
Renderer,
ComponentFactoryResolver,
OpaqueToken
} from '@angular/core';
import {OverlayPortalDirective} from '../directives/overlay-portal.directive';
export const AppRootToken = new OpaqueToken('USERROOT');
@Component({
selector: 'ion-app',
template:
'<div #viewport app-viewport></div>' +
'<div #modalPortal overlay-portal></div>' +
'<div #overlayPortal overlay-portal></div>' +
'<div #loadingPortal class="loading-portal" overlay-portal></div>' +
'<div #toastPortal class="toast-portal" [overlay-portal]="10000"></div>' +
'<div class="click-block"></div>'
})
export class IonicApp implements OnInit{
private _stopScrollPlugin: any;
private _tmr: number;
@ViewChild('viewport', {read: ViewContainerRef}) _viewport: ViewContainerRef;
@ViewChild('modalPortal', { read: OverlayPortalDirective }) _modalPortal: OverlayPortalDirective;
@ViewChild('overlayPortal', { read: OverlayPortalDirective }) _overlayPortal: OverlayPortalDirective;
@ViewChild('loadingPortal', { read: OverlayPortalDirective }) _loadingPortal: OverlayPortalDirective;
@ViewChild('toastPortal', { read: OverlayPortalDirective }) _toastPortal: OverlayPortalDirective;
constructor(
@Inject(AppRootToken) private _userCmp: any,
private _cfr: ComponentFactoryResolver,
elementRef: ElementRef,
public _renderer: Renderer,
){
console.log(this._stopScrollPlugin);
}
ngOnInit(){
/**
* 通過(guò)下面的組件動(dòng)態(tài)的實(shí)例化我們的組件
*/
const factory = this._cfr.resolveComponentFactory(this._userCmp);
const componentRef = this._viewport.createComponent(factory);
this._renderer.setElementClass(componentRef.location.nativeElement, 'app-root', true);
componentRef.changeDetectorRef.detectChanges();
}
}
- 我們使用了
ViewContainerRef進(jìn)行動(dòng)態(tài)組件加載。
ViewContainerRef,正如其名,視圖容器的引用,其實(shí)提供了視圖圖容器操作的api,如下圖,我們想在第一個(gè)div中插入我們的元素,因此我們使用viewchild獲得該div的ViewContainerRef對(duì)象,進(jìn)而進(jìn)行createComponent操作。注意:Root elements of Views attached to this container become siblings of the Anchor Element in the Rendered View(我的理解是如果是容器的根元素被添加進(jìn)容器中,則與錨點(diǎn)是兄弟元素).
其他關(guān)于動(dòng)態(tài)組件加載的知識(shí)可以查看鏈接.


2 . 注意此時(shí)我們定義了export const AppRootToken = new OpaqueToken ('USERROOT'); 來(lái)引導(dǎo)我們自定義的組件。
同時(shí)我們?cè)?code>app.module.ts中增加依賴
{ provide: AppRootToken, useValue: UserRootComponent }//UserRootComponent 自定義的組件
注意:別忘了把自定義組件引入到ngmodule.entryComponents數(shù)組中。
3 . 我們?yōu)榱俗尨a不報(bào)錯(cuò),需要新建一個(gè)指令,如下:
import { Directive,ElementRef,Input } from '@angular/core';
@Directive({
selector: '[overlay-portal]'
})
export class OverlayPortalDirective {
constructor(public elementRef: ElementRef) { }
@Input("overlay-portal")
set _overlayPortal(val: number) {
console.log(`set overlay-portal value ${val}`);
}
}
同時(shí)我們使用下面的方式對(duì)指令進(jìn)行依賴的指定
@ViewChild('modalPortal', { read: OverlayPortalDirective }) _modalPortal: OverlayPortalDirective;
@ViewChild('overlayPortal', { read: OverlayPortalDirective }) _overlayPortal: OverlayPortalDirective;
@ViewChild('loadingPortal', { read: OverlayPortalDirective }) _loadingPortal: OverlayPortalDirective;
@ViewChild('toastPortal', { read: OverlayPortalDirective }) _toastPortal: OverlayPortalDirective;
本文的代碼實(shí)例
本文的文件結(jié)構(gòu)是:
│ index.html
│ main.ts
│ polyfills.ts
│ styles.css
│ test.ts
│ tsconfig.app.json
│ tsconfig.spec.json
│ typings.d.ts
│
├─app
│ │ app-root.ts
│ │ app.module.ts
│ │
│ └─user-root
│ user-root.component.css
│ user-root.component.html
│ user-root.component.spec.ts
│ user-root.component.ts
│
├─assets
│ .gitkeep
│
├─components
├─directives
│ overlay-portal.directive.spec.ts
│ overlay-portal.directive.ts
│
└─environments
environment.prod.ts
environment.ts