SharedModule
是共用模塊的集合地,
此篇分兩篇來介紹常見的幾種共用模塊。
後台製作的過程中,有許多功能是複用的。
此功能模塊是表單驗證
功能。
-src
|-app
|-app.component.css
|-app.component.html
|-app.component.ts
|-app.module.ts
|-config
|-errorcode.ts
|-shared
|-dialog
|-materia
|-pipe
|-validation
|-validation-messages.component.ts
|-validation.directive.ts
|-validation.module.ts
|-validation.service.ts
|-shared.module.ts
後台最多的元件就是表單了,
所以Angular的表單建立跟相關驗證,
建議大家要認真理解。
--
validation-messages.component.ts
:此組件是用來 show 驗證錯誤的訊息。
import { Component, Input } from "@angular/core";
import { FormControl } from "@angular/forms";
@Component({
selector: "validation-messages",
template:
'<div class="error-message" *ngIf="errorMessage !== null">{{errorMessage | translate}}</div>',
styles: [".error-message{color:#DF7607;font-size: x-small;}"]
})
export class ValidationMessagesComponent {
@Input() control: FormControl;
constructor() {}
get errorMessage() {
if (!!this.control) {
for (let propertyName in this.control.errors) {
if (
this.control.errors.hasOwnProperty(propertyName)
&& this.control.touched
) {
return propertyName;
}
}
}
return null;
}
}
--
validation.service.ts
:此檔寫驗證的幾種方式。
import { FormControl } from "@angular/forms";
export class ValidationService {
static userValidator(control: FormControl) {
//英數字+@
if (
!!control.value.match &&
control.value.match(/^(?=.*[0-9])[a-zA-Z0-9!@#$%^&*]{6,100}$/)
) {
return null;
} else {
return { invalidUser: true };
}
}
static integerValidator(control: FormControl) {
//正整数
if (!!control.value.match && control.value.match(/^[1-9]\d*$/)) {
return null;
} else {
return { invalidInteger: true };
}
}
....
}
--
validation.directive.ts
:此指令可以把帶進來的控件做驗證。
import { Input, Directive, forwardRef } from "@angular/core";
import { AbstractControl, NG_VALIDATORS, Validator }
from "@angular/forms";
import { ValidationService } from "./validation.service";
@Directive({
selector: "[fnValidator]",
providers: [
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => ValidationDirective),
multi: true
}
]
})
export class ValidationDirective implements Validator {
@Input() fnValidator: string;
validate(c: AbstractControl): { [key: string]: any } {
return ValidationService[this.fnValidator](c);
}
}
實際運用時:
<input
type="text"
name="idSel"
#idSel="ngModel"
[(ngModel)]="searchValue"
[placeholder]="textholder | translate"
(change)="validSearch(idSel)"
[fnValidator]="'numberOnlyValidator'"
/>
--
validation.module.ts
:import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FormsModule } from "@angular/forms";
import { TranslateModule } from "@ngx-translate/core";
import { ValidationDirective } from "./validation.directive";
import { ValidationService } from "./validation.service";
import { ValidationMessagesComponent } from
"./validation-messages.component";
@NgModule({
providers: [ValidationService],
imports: [CommonModule, FormsModule, TranslateModule],
declarations: [ValidationMessagesComponent, ValidationDirective],
exports: [ValidationMessagesComponent, ValidationDirective]
})
export class ValidationModule {}
此功能模塊是在讀取文章時的特效。
-src
|-app
|-app.component.css
|-app.component.html
|-app.component.ts
|-app.module.ts
|-config
|-errorcode.ts
|-shared
|-dialog
|-materia
|-pipe
|-validation
|-loading
|-loading.component.css
|-loading.component.html
|-loading.component.ts
|-loading.module.ts
|-shared.module.ts
--
loading.component.css
:.loading {
width: 50px;
height: 40px;
text-align: center;
font-size: 10px;
margin: auto;
}
.loading > div {
background-color: #333;
height: 100%;
width: 4px;
display: inline-block;
margin: 0 2px;
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
animation: sk-stretchdelay 1.2s infinite ease-in-out;
}
.loading .rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.loading .rect3 {
-webkit-animation-delay: -1s;
animation-delay: -1s;
}
.loading .rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.loading .rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
@-webkit-keyframes sk-stretchdelay {
0%,
40%,
100% {
-webkit-transform: scaleY(0.4);
}
20% {
-webkit-transform: scaleY(1);
}
}
@keyframes sk-stretchdelay {
0%,
40%,
100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
}
20% {
transform: scaleY(1);
-webkit-transform: scaleY(1);
}
}
--
loading.component.html
:<div class="flex">
<div class="loading">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
</div>
--
loading.component.ts
:import { Component } from "@angular/core";
@Component({
selector: "app-loading",
templateUrl: "./loading.component.html",
styleUrls: ["./loading.component.css"]
})
export class LoadingComponent {
constructor() {}
}
--
loading.module.ts
:import { NgModule } from "@angular/core";
import { LoadingComponent } from "./loading.component";
@NgModule({
declarations: [LoadingComponent],
exports: [LoadingComponent]
})
export class LoadingModule {}
寫一個系統會有很多個子模塊,有些需要的功能模塊相同,
例如表單FormsModule
、ReactiveFormsModule
,
所以把通用的功能模塊彙整到SharedModule裡,
之後要使用的子模塊可直接匯入SharedModule就能使用。
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { TranslateModule } from "@ngx-translate/core";
import { NgxChartsModule } from "@swimlane/ngx-charts";
import { MateriaModule } from "./materia/materia.module";
import { ValidationModule } from "./validation/validation.module";
import { DialogModule } from "./dialog/dialog.module";
import { PipeModule } from "./pipe/pipe.module";
import { LoadingModule } from "./loading/loading.module";
@NgModule({
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
TranslateModule,
DialogModule,
MateriaModule,
PipeModule,
ValidationModule,
LoadingModule
],
exports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
TranslateModule,
DialogModule,
MateriaModule,
PipeModule,
ValidationModule,
LoadingModule
]
})
export class SharedModule {}
其他的模塊匯入SharedModule
@NgModule({
imports: [SharedModule, ...],
declarations: [...],
exports: [...],
providers: [...]
})
可能有人會想說
TranslateModule
在 app.moudle.ts 已經有匯入了,
而且 app.moudle.ts 是全域的,為什麼還要在SharedModule裡面匯入呢?
主因是有可能有好幾個模塊是延遲子路由的方式,
所以吃不到匯入。才會另外寫在這裡。
https://stackblitz.com/edit/ngcms-base