使用Angular可重用Component思路实现一个自带图标(icon)的input控件
參考鏈接:Angular ng-content and Content Projection: A Complete Guide - How To Use ng-content To Improve Component API Design
實現的mockup如下:
初次嘗試:假設我們已經創建好了一個自定義Component,其selector為fa-input, 首先看看如何使用:
@Component({selector: 'app-root',template: `<h1>FA Input</h1><fa-input icon="envelope" (value)="onNewValue($event)"></fa-input><fa-input icon="lock" (value)="onNewValue($event)"></fa-input>` }) export class AppComponent {onNewValue(val) {console.log(val);} }自定義控件fa-input的實現代碼:
@Component({selector: 'fa-input',template: `<i class="fa" [ngClass]="classes"></i><input (focus)="inputFocus = true" (blur)="inputFocus = false"(keyup)="value.emit(input.value)" #input>`, styleUrls: ['./fa-input.component.css'] }) export class FaInputComponent {@Input() icon: string;@Output() value = new EventEmitter<string>();inputFocus = false;get classes() {const cssClasses = {fa: true};cssClasses['fa-' + this.icon] = true;return cssClasses;}@HostBinding('class.focus')get focus() {console.log(this.inputFocus);return this.inputFocus;} }css:
:host {border: 1px solid grey; }input {border: none;outline: none; }:host(.focus) {border: 1px solid blue; }(1) icon屬性決定待顯示的圖標外觀。該自定義控件的使用者需要傳入。
(2) the component has a custom output event named value, that emits new values whenever the value of the text input changes. 一個自定義的名為value的事件發生器,當text input發生變化時,將新的值通知控件使用者。
(3) 檢測原生html input字段的focus和blur事件,設置對應的標志位inputFocus. 再將inputFocus通過@HostBinding綁定到host元素的focus CSS樣式上。
目前這個設計有一些問題:
(1) 沒有考慮到HTML原生的input字段的某些屬性,比如:
<input type="email" autocomplete="off" placeholder='Email'>為了解決這個問題,需要把這些屬性逐一手動遷移到自開發Component中去,但這樣一來,自開發組件的template會膨脹不少:
@Component({selector: 'fa-input',template: `<i class="fa" [ngClass]="classes"></i><input (focus)="inputFocus = true" (blur)="inputFocus = false"(keyup)="value.emit(input.value)" #input [placeholder]="placeholder"[type]="type",[autocomplete]="autocomplete">` }) export class FaInputComponent { ...@Input() placeholder:string;@Input() type:string;@Input() autocomplete:string; ... }這種設計的問題在于,消費者使用自定義控件時,完全不知道自定義控件背后包含一個元素的input字段,這樣,消費者即使想使用原生input字段的某些屬性,也缺乏一種優雅的機制傳入到自定義Component中。
先看改進版本的自定義Component如何消費:
@Component({selector: 'app-root',template: `<h1>FA Input</h1><fa-input icon="envelope"> <input type="email" placeholder="Email"></fa-input> `}) export class AppComponent {}一個明顯的區別,就是原生input控件的出現。
新版使用ng-content的實現:
@Component({selector: 'fa-input',template: `<i class="fa" [ngClass]="classes"></i><ng-content></ng-content>`,styleUrls: ['./fa-input.component.css'] }) export class FaInputComponent {@Input() icon: string;get classes() {const cssClasses = {fa: true};cssClasses['fa-' + this.icon] = true;return cssClasses;} }更多Jerry的原創文章,盡在:“汪子熙”:
總結
以上是生活随笔為你收集整理的使用Angular可重用Component思路实现一个自带图标(icon)的input控件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: chmod 命令用法
- 下一篇: FLASH如何用补间动画制作升国旗