ionic2运行我们的组件

作者: cpu_driver | 来源:发表于2017-04-23 17:09 被阅读319次

    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
            
    

    相关文章

      网友评论

        本文标题:ionic2运行我们的组件

        本文链接:https://www.haomeiwen.com/subject/mxkyzttx.html