在模板中數據綁定,並監聽數據變化。css
<textarea (ngModelChange)="onChange()" [(ngModel)]="val" #text class="autosize" rows="1"></textarea> <textarea class="autosize hidden" rows="1" [value]="val" #text1></textarea>
在textarea.component.ts中增長一個輸入屬性和一個輸出屬性。輸入屬性maxHeight表示textarea的heigh的極限。輸出屬性valChange將會在用戶輸入的數據變化時發出數據。瀏覽器
@Input('max-height') maxHeight = 100; @Output('valChange') valChange = new EventEmitter();
在textarea.component.ts中寫模板中調用的onChange方法。讓text的高度始終等於text1的scrollHeight;這裏是直接操做Dom,建議最好使用Renderer2進行dom的修改。app
onChange() { this.reset(); setTimeout(() => { this.valChange.emit(this.val); this.reset(); }, 0) } reset() { this.text1.nativeElement.style.width = (this.text.nativeElement.scrollWidth + 2) + 'px'; if (this.text1.nativeElement.scrollHeight < this.maxHeight) { this.text.nativeElement.style.height = (this.text1.nativeElement.scrollHeight + 2) + 'px' } }
注意1:這裏獲取scrollwidth的目的是由於不一樣的瀏覽器對滾動條的呈現邏輯有差別,咱們在css中已經設置了text1的overflow=hidden,始終不會讓text1出現滾動條,所以咱們須要讓他的寬度始終等於text1的寬度,以保證當text出現滾動條是他的的寬度也保持一致,從而讓scrollHeight能夠完美映射到text,不然會出現text中明明尚未達到邊界,高度就自行變化了。
注意2:setTimeout中的邏輯是爲了應付事件環,由於咱們監聽的是text的變化,當text中輸入變化時,text1中經過數據綁定獲得的值每每尚未改變,須要等一個節拍。dom
若有須要能夠在此基礎上繼續擴展,使其兼容響應式表單。this
<app-yu-textarea (valChange)="onChange($event)" max-height='100' class="tex"></app-yu-textarea>