Skip to content

Commit bccf8d2

Browse files
authored
fix(textarea): fix change detection error on autosize (#4180)
1 parent 8d0cd04 commit bccf8d2

File tree

1 file changed

+46
-13
lines changed

1 file changed

+46
-13
lines changed

src/lib/input/autosize.ts

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,36 @@ import {Directive, ElementRef, Input, AfterViewInit} from '@angular/core';
1010
exportAs: 'mdTextareaAutosize',
1111
host: {
1212
'(input)': 'resizeToFitContent()',
13-
'[style.min-height]': '_minHeight',
14-
'[style.max-height]': '_maxHeight',
1513
},
1614
})
1715
export class MdTextareaAutosize implements AfterViewInit {
16+
private _minRows: number;
17+
private _maxRows: number;
18+
1819
/** @deprecated Use mdAutosizeMinRows */
19-
@Input() minRows: number;
20+
@Input()
21+
get minRows() { return this._minRows; }
22+
23+
set minRows(value: number) {
24+
this._minRows = value;
25+
this._setMinHeight();
26+
}
27+
28+
/** @deprecated Use mdAutosizeMaxRows */
29+
@Input()
30+
get maxRows() { return this._maxRows; }
31+
32+
set maxRows(value: number) {
33+
this._maxRows = value;
34+
this._setMaxHeight();
35+
}
2036

2137
/** Minimum number of rows for this textarea. */
2238
@Input()
2339
get mdAutosizeMinRows(): number { return this.minRows; }
2440
set mdAutosizeMinRows(value: number) { this.minRows = value; }
2541

26-
/** @deprecated Use mdAutosizeMaxRows */
27-
@Input() maxRows: number;
28-
29-
/** Minimum number of rows for this textarea. */
42+
/** Maximum number of rows for this textarea. */
3043
@Input()
3144
get mdAutosizeMaxRows(): number { return this.maxRows; }
3245
set mdAutosizeMaxRows(value: number) { this.maxRows = value; }
@@ -36,21 +49,37 @@ export class MdTextareaAutosize implements AfterViewInit {
3649

3750
constructor(private _elementRef: ElementRef) { }
3851

39-
/** The minimum height of the textarea as determined by minRows. */
40-
get _minHeight() {
41-
return this.minRows ? `${this.minRows * this._cachedLineHeight}px` : null;
52+
/** Sets the minimum height of the textarea as determined by minRows. */
53+
_setMinHeight(): void {
54+
const minHeight = this.minRows && this._cachedLineHeight ?
55+
`${this.minRows * this._cachedLineHeight}px` : null;
56+
57+
if (minHeight) {
58+
this._setTextareaStyle('minHeight', minHeight);
59+
}
4260
}
4361

44-
/** The maximum height of the textarea as determined by maxRows. */
45-
get _maxHeight() {
46-
return this.maxRows ? `${this.maxRows * this._cachedLineHeight}px` : null;
62+
/** Sets the maximum height of the textarea as determined by maxRows. */
63+
_setMaxHeight(): void {
64+
const maxHeight = this.maxRows && this._cachedLineHeight ?
65+
`${this.maxRows * this._cachedLineHeight}px` : null;
66+
67+
if (maxHeight) {
68+
this._setTextareaStyle('maxHeight', maxHeight);
69+
}
4770
}
4871

4972
ngAfterViewInit() {
5073
this._cacheTextareaLineHeight();
5174
this.resizeToFitContent();
5275
}
5376

77+
/** Sets a style property on the textarea element. */
78+
private _setTextareaStyle(property: string, value: string): void {
79+
const textarea = this._elementRef.nativeElement as HTMLTextAreaElement;
80+
textarea.style[property] = value;
81+
}
82+
5483
/**
5584
* Cache the height of a single-row textarea.
5685
*
@@ -79,6 +108,10 @@ export class MdTextareaAutosize implements AfterViewInit {
79108
textarea.parentNode.appendChild(textareaClone);
80109
this._cachedLineHeight = textareaClone.clientHeight;
81110
textarea.parentNode.removeChild(textareaClone);
111+
112+
// Min and max heights have to be re-calculated if the cached line height changes
113+
this._setMinHeight();
114+
this._setMaxHeight();
82115
}
83116

84117
/** Resize the textarea to fit its content. */

0 commit comments

Comments
 (0)