最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
当前位置: 首页 - 科技 - 知识百科 - 正文

动手写一个angular版本的Message组件的方法

来源:懂视网 责编:小采 时间:2020-11-27 22:23:35
文档

动手写一个angular版本的Message组件的方法

动手写一个angular版本的Message组件的方法:学习一个框架或库的最好方法是看官方文档,并着手去写例子。最近在利用空闲的时间学习angular,那今天就尝试写一个message组件,并通过message服务动态加载message组件。 我所参与的项目基本是用jquery完成的。之前,在项目中自己动手写过一个简单的mess
推荐度:
导读动手写一个angular版本的Message组件的方法:学习一个框架或库的最好方法是看官方文档,并着手去写例子。最近在利用空闲的时间学习angular,那今天就尝试写一个message组件,并通过message服务动态加载message组件。 我所参与的项目基本是用jquery完成的。之前,在项目中自己动手写过一个简单的mess

学习一个框架或库的最好方法是看官方文档,并着手去写例子。最近在利用空闲的时间学习angular,那今天就尝试写一个message组件,并通过message服务动态加载message组件。
我所参与的项目基本是用jquery完成的。之前,在项目中自己动手写过一个简单的message插件,样子如下图。

那现在就使用angular(版本5.0.0)来实现message组件。

message组件

message组件要根据传入的类型、消息和duration来显示。创建三个文件:message.component.ts,message.component.html,message.component.css,代码如下。

//message.component.ts
import {Component,Input,OnInit,ChangeDetectionStrategy} from '@angular/core';
import {
 trigger,
 state,
 style,
 transition,
 animate
 } from '@angular/animations';
const mapping={
 success:'glyphicon-ok-sign',
 warning:'glyphicon-exclamation-sign',
 error:'glyphicon-exclamation-sign',
 info:'glyphicon-ok-circle'
}
@Component({
 selector:'upc-ng-message',
 templateUrl:'./message.component.html',
 styleUrls:['./message.component.css'],
 changeDetection:ChangeDetectionStrategy.OnPush
})
export class MessageComponent implements OnInit{
 ngOnInit(): void {
 this.typeClass=['upc-message-' + this.msgType];
 this.typeIconClass=[mapping[this.msgType]];
 }
 @Input() msgType:'success' | 'info' | 'warning' | 'error'='info'

 @Input() payload:string = ''

 private typeClass
 private typeIconClass
}

<!--*message.component.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%;
 top: 36px;
 left: 0;
 pointer-events: none;
 padding: 8px;
 text-align: center;
 }
 .upc-message i {
 margin-right: 8px;
 font-size: 14px;
 top: 1px;
 position: relative;
 }
 .upc-message-success 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来完成。使用ComponentFactoryResolver创建ComponentFactory,再通过ComponentFactory的create方法创建组件。看官方文档中API的说明,ComponentFactory的create方法至少需要一个injector参数,而injector的创建在文档中也有提到,其中参数providers为需要注入的类。再梳理下整个过程:

  1. 提供providers
  2. 创建Injector实例
  3. 创建ComponetFactory
  4. 使用ComponetFactory创建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方法用于初始化ComponetFactory(参数为组件类型);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 _componentFactory: ComponentFactory<T>
 attch(componentType: Type<T>): ComponentLoader<T> {
 this._componentFactory = this._cfr.resolveComponentFactory<T>(componentType);
 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 componentRef = this._componentFactory.create(injector);
 Object.assign(componentRef.instance, opts);
 if (this._parent) {
 this._parent.appendChild(componentRef.location.nativeElement);
 }
 componentRef.changeDetectorRef.markForCheck();
 componentRef.changeDetectorRef.detectChanges();
 return componentRef;
 }
 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 './component-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 '../component-loader/component-loader.factory';
import {MessageComponent} from './message.component';
import {ComponentLoader} from '../component-loader/component-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 success(payload,duration?) {
 this.createMessage('success',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/common';
import {MessageComponent} from './message.component';
import {MessageService} from './message.service';
import {ComponentLoaderFactory} from '../component-loader/component-loader.factory';

@NgModule({
 imports:[CommonModule],
 declarations:[MessageComponent],
 providers:[MessageService,ComponentLoaderFactory],
 entryComponents:[MessageComponent],
 exports:[MessageComponent]
})
export class MessageModule{
}

使用方法

注入MessageService,调用API使用Message组件。

this._msgService.success('成功了!');

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文档

动手写一个angular版本的Message组件的方法

动手写一个angular版本的Message组件的方法:学习一个框架或库的最好方法是看官方文档,并着手去写例子。最近在利用空闲的时间学习angular,那今天就尝试写一个message组件,并通过message服务动态加载message组件。 我所参与的项目基本是用jquery完成的。之前,在项目中自己动手写过一个简单的mess
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top