最新文章專題視頻專題問(wèn)答1問(wèn)答10問(wèn)答100問(wèn)答1000問(wèn)答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題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關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問(wèn)答文章1 問(wèn)答文章501 問(wèn)答文章1001 問(wèn)答文章1501 問(wèn)答文章2001 問(wèn)答文章2501 問(wèn)答文章3001 問(wèn)答文章3501 問(wèn)答文章4001 問(wèn)答文章4501 問(wèn)答文章5001 問(wèn)答文章5501 問(wèn)答文章6001 問(wèn)答文章6501 問(wèn)答文章7001 問(wèn)答文章7501 問(wèn)答文章8001 問(wèn)答文章8501 問(wèn)答文章9001 問(wèn)答文章9501
當(dāng)前位置: 首頁(yè) - 科技 - 知識(shí)百科 - 正文

動(dòng)手寫(xiě)一個(gè)angular版本的Message組件的方法

來(lái)源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 22:23:35
文檔

動(dòng)手寫(xiě)一個(gè)angular版本的Message組件的方法

動(dòng)手寫(xiě)一個(gè)angular版本的Message組件的方法:學(xué)習(xí)一個(gè)框架或庫(kù)的最好方法是看官方文檔,并著手去寫(xiě)例子。最近在利用空閑的時(shí)間學(xué)習(xí)angular,那今天就嘗試寫(xiě)一個(gè)message組件,并通過(guò)message服務(wù)動(dòng)態(tài)加載message組件。 我所參與的項(xiàng)目基本是用jquery完成的。之前,在項(xiàng)目中自己動(dòng)手寫(xiě)過(guò)一個(gè)簡(jiǎn)單的mess
推薦度:
導(dǎo)讀動(dòng)手寫(xiě)一個(gè)angular版本的Message組件的方法:學(xué)習(xí)一個(gè)框架或庫(kù)的最好方法是看官方文檔,并著手去寫(xiě)例子。最近在利用空閑的時(shí)間學(xué)習(xí)angular,那今天就嘗試寫(xiě)一個(gè)message組件,并通過(guò)message服務(wù)動(dòng)態(tài)加載message組件。 我所參與的項(xiàng)目基本是用jquery完成的。之前,在項(xiàng)目中自己動(dòng)手寫(xiě)過(guò)一個(gè)簡(jiǎn)單的mess

學(xué)習(xí)一個(gè)框架或庫(kù)的最好方法是看官方文檔,并著手去寫(xiě)例子。最近在利用空閑的時(shí)間學(xué)習(xí)angular,那今天就嘗試寫(xiě)一個(gè)message組件,并通過(guò)message服務(wù)動(dòng)態(tài)加載message組件。
我所參與的項(xiàng)目基本是用jquery完成的。之前,在項(xiàng)目中自己動(dòng)手寫(xiě)過(guò)一個(gè)簡(jiǎn)單的message插件,樣子如下圖。

那現(xiàn)在就使用angular(版本5.0.0)來(lái)實(shí)現(xiàn)message組件。

message組件

message組件要根據(jù)傳入的類型、消息和duration來(lái)顯示。創(chuàng)建三個(gè)文件: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

通過(guò)官方文檔動(dòng)態(tài)組件一節(jié),可以了解動(dòng)態(tài)創(chuàng)建組件需要通過(guò)ComponentFactoryResolver來(lái)完成。使用ComponentFactoryResolver創(chuàng)建ComponentFactory,再通過(guò)ComponentFactory的create方法創(chuàng)建組件??垂俜轿臋n中API的說(shuō)明,ComponentFactory的create方法至少需要一個(gè)injector參數(shù),而injector的創(chuàng)建在文檔中也有提到,其中參數(shù)providers為需要注入的類。再梳理下整個(gè)過(guò)程:

  1. 提供providers
  2. 創(chuàng)建Injector實(shí)例
  3. 創(chuàng)建ComponetFactory
  4. 使用ComponetFactory創(chuàng)建ComponentRef
//ComponentFactory的create方法
create(injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string|any, ngModule?: NgModuleRef<any>): ComponentRef<C>

//使用Injector的create創(chuàng)建injector實(shí)例
static create(providers: StaticProvider[], parent?: Injector): Injector

為了代碼的復(fù)用,這里創(chuàng)建通用的loader類來(lái)完成組件的動(dòng)態(tài)創(chuàng)建。其中,attch方法用于初始化ComponetFactory(參數(shù)為組件類型);to方法用于標(biāo)識(shí)組件的父容器;provider方法用于初始化可注入的類;create方法用于創(chuàng)建組件并手動(dòng)變更檢測(cè);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;
 }
}

同時(shí),為了便于loader的創(chuàng)建,再創(chuàng)建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。記得要把動(dòng)態(tài)創(chuàng)建的組件添加到entryComponents數(shù)組中。

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,調(diào)用API使用Message組件。

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

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

動(dòng)手寫(xiě)一個(gè)angular版本的Message組件的方法

動(dòng)手寫(xiě)一個(gè)angular版本的Message組件的方法:學(xué)習(xí)一個(gè)框架或庫(kù)的最好方法是看官方文檔,并著手去寫(xiě)例子。最近在利用空閑的時(shí)間學(xué)習(xí)angular,那今天就嘗試寫(xiě)一個(gè)message組件,并通過(guò)message服務(wù)動(dòng)態(tài)加載message組件。 我所參與的項(xiàng)目基本是用jquery完成的。之前,在項(xiàng)目中自己動(dòng)手寫(xiě)過(guò)一個(gè)簡(jiǎn)單的mess
推薦度:
  • 熱門(mén)焦點(diǎn)

最新推薦

猜你喜歡

熱門(mén)推薦

專題
Top