ionic2運(yùn)行我們的組件

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();
  }
}
  1. 我們使用了 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í)可以查看鏈接.

未實(shí)例化自定義之前
實(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
        
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,001評(píng)論 25 709
  • 本文使用Ionic2從頭建立一個(gè)簡(jiǎn)單的Todo應(yīng)用,讓用戶可以做以下事情: 查看todo列表 添加新的todo項(xiàng) ...
    孫亖閱讀 8,665評(píng)論 13 29
  • Ionic是一個(gè)基于Angular2的開(kāi)發(fā)手機(jī)web app的框架,它包含了一整套手機(jī)端的樣式組件,和一系列的功能...
    王兆龍閱讀 1,288評(píng)論 1 1
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,547評(píng)論 19 139
  • 只有在春天(原創(chuàng)) 一顆芽,一片葉,一朵不名目的野花,任何枯草里、枯木上、石縫里、荒蕪里、墻腳里鉆出來(lái)的,都會(huì)引來(lái)...
    千譽(yù)嘉言閱讀 552評(píng)論 19 16

友情鏈接更多精彩內(nèi)容