在模板中数据绑定,并监听数据变化。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>