麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 編程 > JavaScript > 正文

動手寫一個angular版本的Message組件的方法

2019-11-19 14:43:21
字體:
來源:轉載
供稿:網友

學習一個框架或庫的最好方法是看官方文檔,并著手去寫例子。最近在利用空閑的時間學習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.tsimport {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('成功了!');

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 免费国产不卡午夜福在线 | av电影在线观看网址 | 曰韩黄色片 | 人人舔人人射 | 99这里有精品 | 国产亚洲精品久久久闺蜜 | 欧美成人精品欧美一级乱黄 | 国产精品成人免费一区久久羞羞 | 欧美日韩一 | 亚洲乱妇19p | 欧美性生活视频免费看 | 成人免费毛片在线观看 | aa久久 | 性生活香蕉视频 | 久久精品美乳 | 成人情欲视频在线看免费 | 成人三级视频网站 | 精品一区二区三区在线视频 | 夜添久久精品亚洲国产精品 | 在线高清中文字幕 | 欧美成人高清视频 | 欧美18一19sex性护士农村 | 蜜桃久久一区二区三区 | 亚洲特黄a级毛片在线播放 久久久入口 | 国产亚洲美女精品久久久2020 | 国产九色在线观看 | 日本在线国产 | 欧美性受xxxx人人本视频 | 久久精品2019中文字幕 | 欧美人的天堂一区二区三区 | www亚洲免费 | 欧产日产国产精品v | 一区二区三区在线观看免费视频 | 美国人成人在线视频 | 国产电影av在线 | 久久国产精品免费视频 | 黄色网址免费在线 | 深夜福利视频绿巨人视频在线观看 | 欧美成人免费电影 | h视频在线免费观看 | 国产亚洲精品久久久久久久久 |