尝试在Ionic&Angular项目中创建一个密码输入框的组件。跟我们在移动端输入密码的行为类似,输入框的右侧有一个眼睛的图标,点击图标就可以显示或隐藏密码。
具体思路是,我们利用Angular的ng-content
来讲输入框透传到组件里面,这样组件其实不用很关注输入框的东西,只需要关注交互就行了。关于内容投影以前也针对Angular写过一篇文章,可以参照:Angular ng-content 内容投影。
创建组件
我们创建一个名为show-hide-password
的组件:
1
| $ ng g c show-hide-password
|
这个组件接受ion-input
元素的透传,所以我们通过ContentChild
来捕获这个元素:
1
| @ContentChild(IonInput) input: IonInput;
|
我们需要一个变量来记录并控制密码的展示与否:
1 2 3 4 5
| showPassword = false; toggleShow() { this.showPassword = !this.showPassword; this.input.type = this.showPassword ? 'text' : 'password'; }
|
完整的show-hide-password.component.ts
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import {Component, ContentChild, OnInit} from '@angular/core'; import {IonInput} from '@ionic/angular';
@Component({ selector: 'app-show-hide-password', templateUrl: './show-hide-password.component.html', styleUrls: ['./show-hide-password.component.scss'], }) export class ShowHidePasswordComponent implements OnInit { @ContentChild(IonInput) input: IonInput;
showPassword = false;
constructor() { }
ngOnInit() { }
toggleShow() { this.showPassword = !this.showPassword; this.input.type = this.showPassword ? 'text' : 'password'; }
}
|
然后看模板文件,我们需要一个ng-content
来接受投影,然后需要一个眼睛的图标控制这个投影的元素:
1 2 3 4 5
| <ng-content></ng-content> <a class="type-toggle" (click)="toggleShow()"> <ion-icon class="show-option" name="eye-off-outline" [hidden]="showPassword"></ion-icon> <ion-icon class="hide-option" name="eye-outline" [hidden]="!showPassword"></ion-icon> </a>
|
相关样式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| :host{ display: flex; width: 100%; align-items: center; .type-toggle{ padding-inline-start: 0.5rem; } .show-option, .hide-option{ font-size: 1.2rem; display: block; &:not(ion-icon) { text-transform: uppercase; font-size: 1rem; } } }
|
组件这样基本就可以了。
应用组件
我们只需要在需要使用html中:
1 2 3 4 5 6
| <ion-item> <ion-label>密码</ion-label> <app-show-hide-password> <ion-input type="password" placeholder=""></ion-input> </app-show-hide-password> </ion-item>
|
这样就OK了。
真的 OK了吗?????
我们看下页面,嘎,只有input元素,没有眼睛。
再仔细看看,好像只渲染<ion-input>
元素,<app-show-hide-passsword>
简直就是个摆设,在app-show-hide-password.component.ts
的contruct
和ngOnInit
函数里面打断点都没用,得,根本就没进组件。
再仔细回想下,为了方便管理,我把通用组件都放在了app/components/
目录下,组件归属于components.module.ts
。组件声明于一个module
,应用于另一个module
,那这这这???
在Angular里面已经不需要特意去entryComponents
声明了啊,难道在ionic里面还需要?
得,加上吧。在包含组件的模块中需要导出组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {ShowHidePasswordComponent} from './show-hide-password/show-hide-password.component'; import {IonicModule} from '@ionic/angular';
@NgModule({ declarations: [ ShowHidePasswordComponent, ], imports: [ CommonModule, IonicModule, ], exports: [ ShowHidePasswordComponent ] }) export class ComponentsModule { }
|
在应用组件的模块需要在entryComponents
里面声明组件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {ComponentsModule} from '../../core/components/components.module'; import {LoginComponent} from './login/login.component'; import {ShowHidePasswordComponent} from '../../core/components/show-hide-password/show-hide-password.component'; import {IonicModule} from '@ionic/angular';
@NgModule({ declarations: [ LoginComponent, ], imports: [ CommonModule, ComponentsModule, IonicModule, ], entryComponents: [ ShowHidePasswordComponent, ] }) export class IndependenceModule { }
|
再看页面预览:
嗯,现在nice了。
Ionic中的angular和真正的Angular项目还是有点区别的,需要特殊对待。真闹心