动手写一个angular版本的Message组件的方法
学习一个框架或库的最好方法是看官方文档,并着手去写例子。最近在利用空闲的时间学习angular,那今天就尝试写一个message组件,并通过message服务动态加载message组件。
我所参与的项目基本是用jquery完成的。之前,在项目中自己动手写过一个简单的message插件,样子如下图。
那现在就使用angular(版本5.0.0)来实现message组件。
message组件
message组件要根据传入的类型、消息和duration来显示。创建三个文件:message.ponent.ts,message.ponent.html,message.ponent.css,代码如下。
//message.ponent.ts import {Component,Input,OnInit,ChangeDetectionStrategy} from '@angular/core'; import { trigger, state, style, transition, animate } from '@angular/animations'; const mapping={ suess:'glyphicon-ok-sign', warning:'glyphicon-exclamation-sign', error:'glyphicon-exclamation-sign', info:'glyphicon-ok-circle' } @Component({ selector:'upc-ng-message', templateUrl:'./message.ponent.html', styleUrls:['./message.ponent.css'], changeDetection:ChangeDetectionStrategy.OnPush }) export class MessageComponent implements OnInit{ ngOnInit(): void { this.typeClass=['upc-message-' + this.msgType]; this.typeIconClass=[mapping[this.msgType]]; } @Input() msgType:'suess' | 'info' | 'warning' | 'error'='info' @Input() payload:string = '' private typeClass private typeIconClass }
<!--*message.ponent.html--> <div class="upc-message"> <div class="upc-message-content" [ngClass]="typeClass"> <i class="glyphicon" [ngClass]="typeIconClass"></i> {{payload}} </div> </div>
.upc-message { position: fixed; z-index: 1999; width: 100%; : 36px; left: 0; pointer-events: none; padding: 8px; text-align: center; } .upc-message i { margin-right: 8px; font-size: 14px; : 1px; position: relative; } .upc-message-suess i { color: green; } .upc-message-warning i { color: yellow; } .upc-message-error i { color: red; } .upc-message-content { padding: 8px 16px; -ms-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: 0 2px 8px #000000; -ms-box-shadow: 0 2px 8px #000000; box-shadow: 0 2px 8px #000000; box-shadow: 0 2px 8px rgba(0,0,0,.2); background: #fff; display: inline-block; pointer-events: all; }
ComponentLoader
通过官方文档一节,可以了解动态创建组件需要通过来完成。使用ComponentFactoryResolver创建,再通过ComponentFactory的create方法创建组件。看官方文档中API的说明,ComponentFactory的create方法至少需要一个injector参数,而的创建在文档中也有提到,其中参数providers为需要注入的类。再梳理下整个过程:
- 提供providers
- 创建Injector实例
- 创建CompoFactory
- 使用CompoFactory创建ComponentRef
//ComponentFactory的create方法 create(injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string|any, ngModule?: NgModuleRef<any>): ComponentRef<C> //使用Injector的create创建injector实例 static create(providers: StaticProvider[], parent?: Injector): Injector
为了代码的复用,这里创建通用的loader类来完成组件的动态创建。其中,attch方法用于初始化CompoFactory(参数为组件类型);to方法用于标识组件的父容器;provider方法用于初始化可注入的类;create方法用于创建组件并手动变更检测;remove方法用于移除组件。
import { ComponentFactoryResolver, ComponentFactory, ComponentRef, Type, Injector, Provider, ElementRef } from '@angular/core'; export class ComponentLoader<T>{ constructor(private _cfr: ComponentFactoryResolver, private _injector: Injector) { } private _ponentFactory: ComponentFactory<T> attch(ponentType: Type<T>): ComponentLoader<T> { this._ponentFactory = this._cfr.resolveComponentFactory<T>(ponentType); return this; } private _parent: Element to(parent: string | ElementRef): ComponentLoader<T> { if (parent instanceof ElementRef) { this._parent = parent.nativeElement; } else { this._parent = document.querySelector(parent); } return this; } private _providers: Provider[] = []; provider(provider: Provider) { this._providers.push(provider); } create(opts: {}): ComponentRef<T> { const injector = Injector.create(this._providers as any[], this._injector); const ponentRef = this._ponentFactory.create(injector); Object.assign(ponentRef.instance, opts); if (this._parent) { this._parent.appendChild(ponentRef.location.nativeElement); } ponentRef.changeDetectorRef.markForCheck(); ponentRef.changeDetectorRef.detectChanges(); return ponentRef; } remove(ref:ComponentRef<T>){ if(this._parent){ this._parent.removeChild(ref.location.nativeElement) } ref=null; } }
同时,为了便于loader的创建,再创建LoaderFactory类,代码如下:
import { ComponentFactoryResolver, Injector, Injectable, ElementRef } from '@angular/core'; import { ComponentLoader } from './ponent-loader.class'; @Injectable() export class ComponentLoaderFactory { constructor(private _injector: Injector, private _cfr: ComponentFactoryResolver) { } create<T>(): ComponentLoader<T> { return new ComponentLoader(this._cfr, this._injector); } }
message service
message service提供显示message的API,代码如下:
import {Injectable,Injector} from '@angular/core'; import { ComponentLoaderFactory } from '../ponent-loader/ponent-loader.factory'; import {MessageComponent} from './message.ponent'; import {ComponentLoader} from '../ponent-loader/ponent-loader.class'; @Injectable() export class MessageService{ constructor(private _clf:ComponentLoaderFactory,private _injector:Injector){ this.loader=this._clf.create<MessageComponent>(); } private loader:ComponentLoader<MessageComponent> private createMessage(t,c,duration=2000){ this.loader.attch(MessageComponent).to('body'); const opts = { msgType: t, payload:c }; const ref = this.loader.create(opts); ref.changeDetectorRef.markForCheck(); ref.changeDetectorRef.detectChanges(); let self=this; let st = setTimeout(() => { self.loader.remove(ref); }, duration); } public info(payload,duration?) { this.createMessage('info',payload,duration); } public suess(payload,duration?) { this.createMessage('suess',payload,duration); } public error(payload,duration?) { this.createMessage('error',payload,duration); } public warning(payload,duration?) { this.createMessage('warning',payload,duration); } }
message.module
最后,增加message.module.ts。记得要把动态创建的组件添加到entryComponents数组中。
import {NgModule} from '@angular/core'; import { CommonModule } from '@angular/mon'; import {MessageComponent} from './message.ponent'; import {MessageService} from './message.service'; import {ComponentLoaderFactory} from '../ponent-loader/ponent-loader.factory'; @NgModule({ imports:[CommonModule], declarations:[MessageComponent], providers:[MessageService,ComponentLoaderFactory], entryComponents:[MessageComponent], exports:[MessageComponent] }) export class MessageModule{ }
使用方法
注入MessageService,调用API使用Message组件。
this._msgService.suess('成功了!');
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持狼蚁SEO。
编程语言
- 机械手焊接机器人编程 机械手焊接设备编程
- vb数据库编程实例,vb做数据库
- tiobe世界编程语言排行榜,全球编程语言排行
- 成都java编程培训 成都it编程培训中心
- 编程基础培训,编程基础知识培训
- flash游戏编程基础教程,flash游戏开发教程
- 不会英语能学编程吗 不会英语可以学程序员吗
- 爱心代码编程C语言 爱心代码编程c语言公式
- c语言编程学习入门 c语言编程快速入门
- 西门子plc编程培训 西门子plc编程培训班
- 哪里可以学编程 台州哪里可以学编程
- 少儿编程哪个好 少儿编程哪个品牌好
- 编程是什么意思,图形编程是什么意思
- c语言编程软件下载,c语言编程软件在哪下载
- java编程软件下载,java编程下载手机版
- ug编程培训学校,ug编程培训教程