ionic2運行我們的組件

ionic2是一款比較優秀的基于angular的移動端框架,其源碼蘊含了豐富的設計思想,我們本文講一起學習ionic如何如何運行我們自己寫的業務代碼的。下面我將在angular工程的基礎上進行ionic框架的搭建。今天我們將從ionic的ion-app標簽開始進行學習,以實現我們最簡化的ionic程序.


之前我們在寫ionic,曾在app.module.ts中,使用如下的代碼:

@NgModule({
  declarations: [... ],
  imports: [
    IonicModule.forRoot(...)
  ],
  bootstrap: [IonicApp],
  entryComponents: [...],
  providers: [...]
})

想必很多人沒有關心過bootstrap: [IonicApp],我們也不會去隨便更改這一句代碼。如果是標準的ionic程序,修改這條語句,會報錯
這一句話在ionic包的app-root.ts中定義,在這里我們就不去解釋源碼了。
下面我對原來的app-root.ts進行了簡化,大概的模樣如下:

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(){
    /**
     * 通過下面的組件動態的實例化我們的組件
     */
     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進行動態組件加載。

ViewContainerRef,正如其名,視圖容器的引用,其實提供了視圖圖容器操作的api,如下圖,我們想在第一個div中插入我們的元素,因此我們使用viewchild獲得該div的ViewContainerRef對象,進而進行createComponent操作。注意:Root elements of Views attached to this container become siblings of the Anchor Element in the Rendered View(我的理解是如果是容器的根元素被添加進容器中,則與錨點是兄弟元素).
其他關于動態組件加載的知識可以查看鏈接.

未實例化自定義之前
實例化自定義之后

2 . 注意此時我們定義了export const AppRootToken = new OpaqueToken ('USERROOT'); 來引導我們自定義的組件。

同時我們在app.module.ts中增加依賴

 { provide: AppRootToken, useValue: UserRootComponent }//UserRootComponent 自定義的組件

注意:別忘了把自定義組件引入到ngmodule.entryComponents數組中。
3 . 我們為了讓代碼不報錯,需要新建一個指令,如下:

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}`);
  }

}

同時我們使用下面的方式對指令進行依賴的指定

 @ViewChild('modalPortal', { read: OverlayPortalDirective }) _modalPortal: OverlayPortalDirective;
  @ViewChild('overlayPortal', { read: OverlayPortalDirective }) _overlayPortal: OverlayPortalDirective;
  @ViewChild('loadingPortal', { read: OverlayPortalDirective }) _loadingPortal: OverlayPortalDirective;
  @ViewChild('toastPortal', { read: OverlayPortalDirective }) _toastPortal: OverlayPortalDirective;

本文的代碼實例
本文的文件結構是:

│  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
        
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,845評論 25 708
  • 本文使用Ionic2從頭建立一個簡單的Todo應用,讓用戶可以做以下事情: 查看todo列表 添加新的todo項 ...
    孫亖閱讀 8,593評論 13 29
  • Ionic是一個基于Angular2的開發手機web app的框架,它包含了一整套手機端的樣式組件,和一系列的功能...
    王兆龍閱讀 1,205評論 1 1
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • 只有在春天(原創) 一顆芽,一片葉,一朵不名目的野花,任何枯草里、枯木上、石縫里、荒蕪里、墻腳里鉆出來的,都會引來...
    千譽嘉言閱讀 508評論 19 16