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
        
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,373评论 25 707
  • 本文使用Ionic2从头建立一个简单的Todo应用,让用户可以做以下事情: 查看todo列表 添加新的todo项 ...
    孙亖阅读 8,565评论 13 29
  • Ionic是一个基于Angular2的开发手机web app的框架,它包含了一整套手机端的样式组件,和一系列的功能...
    王兆龙阅读 1,161评论 1 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • 只有在春天(原创) 一颗芽,一片叶,一朵不名目的野花,任何枯草里、枯木上、石缝里、荒芜里、墙脚里钻出来的,都会引来...
    千誉嘉言阅读 480评论 19 16