mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(form-field): always use native input value to determine whether control is empty (#13307)
Currently we use the input value accessor to figure out whether an input has a value. This doesn't handle the case with `matDatepicker` where we have a custom accessor whose model value may not change, even though the value in the input has changed. These changes switch to always using the value from the input element. Fixes #13305.
This commit is contained in:
committed by
Jeremy Elbourn
parent
845388cdaa
commit
10e6502147
@@ -5,7 +5,15 @@ import {
|
||||
wrappedErrorMessage,
|
||||
MockNgZone,
|
||||
} from '@angular/cdk/testing';
|
||||
import {ChangeDetectionStrategy, Component, ViewChild, Type, Provider, NgZone} from '@angular/core';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
ViewChild,
|
||||
Type,
|
||||
Provider,
|
||||
NgZone,
|
||||
Directive,
|
||||
} from '@angular/core';
|
||||
import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing';
|
||||
import {
|
||||
FormControl,
|
||||
@@ -35,8 +43,7 @@ import {By} from '@angular/platform-browser';
|
||||
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
|
||||
import {MatStepperModule} from '@angular/material/stepper';
|
||||
import {MatTabsModule} from '@angular/material/tabs';
|
||||
import {MatInputModule} from './index';
|
||||
import {MatInput} from './input';
|
||||
import {MatInputModule, MatInput, MAT_INPUT_VALUE_ACCESSOR} from './index';
|
||||
import {MatTextareaAutosize} from './autosize';
|
||||
|
||||
describe('MatInput without forms', () => {
|
||||
@@ -889,6 +896,20 @@ describe('MatInput without forms', () => {
|
||||
expect(formField.classList).not.toContain('mat-form-field-type-mat-native-select');
|
||||
});
|
||||
|
||||
it('should use the native input value when determining whether ' +
|
||||
'the element is empty with a custom accessor', fakeAsync(() => {
|
||||
let fixture = createComponent(MatInputWithCustomAccessor, [], [], [CustomMatInputAccessor]);
|
||||
fixture.detectChanges();
|
||||
let label = fixture.debugElement.query(By.css('label')).nativeElement;
|
||||
|
||||
expect(label.classList).toContain('mat-form-field-empty');
|
||||
|
||||
fixture.nativeElement.querySelector('input').value = 'abc';
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(label.classList).not.toContain('mat-form-field-empty');
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
describe('MatInput with forms', () => {
|
||||
@@ -1368,7 +1389,8 @@ describe('MatInput with textarea autosize', () => {
|
||||
|
||||
function createComponent<T>(component: Type<T>,
|
||||
providers: Provider[] = [],
|
||||
imports: any[] = []): ComponentFixture<T> {
|
||||
imports: any[] = [],
|
||||
declarations: any[] = []): ComponentFixture<T> {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
FormsModule,
|
||||
@@ -1379,7 +1401,7 @@ function createComponent<T>(component: Type<T>,
|
||||
ReactiveFormsModule,
|
||||
...imports
|
||||
],
|
||||
declarations: [component],
|
||||
declarations: [component, ...declarations],
|
||||
providers,
|
||||
}).compileComponents();
|
||||
|
||||
@@ -1876,3 +1898,26 @@ class MatInputSelectWithLabel {}
|
||||
</mat-form-field>`
|
||||
})
|
||||
class MatInputSelectWithInnerHtml {}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<mat-form-field floatLabel="never">
|
||||
<input matInput customInputAccessor placeholder="Placeholder">
|
||||
</mat-form-field>`
|
||||
})
|
||||
class MatInputWithCustomAccessor {}
|
||||
|
||||
|
||||
/** Custom component that never has a value. Used for testing the `MAT_INPUT_VALUE_ACCESSOR`. */
|
||||
@Directive({
|
||||
selector: 'input[customInputAccessor]',
|
||||
providers: [{
|
||||
provide: MAT_INPUT_VALUE_ACCESSOR,
|
||||
useExisting: CustomMatInputAccessor
|
||||
}]
|
||||
})
|
||||
class CustomMatInputAccessor {
|
||||
get value() { return this._value; }
|
||||
set value(_value: any) {}
|
||||
private _value = null;
|
||||
}
|
||||
|
||||
@@ -332,7 +332,7 @@ export class MatInput extends _MatInputMixinBase implements MatFormFieldControl<
|
||||
|
||||
/** Does some manual dirty checking on the native input `value` property. */
|
||||
protected _dirtyCheckNativeValue() {
|
||||
const newValue = this.value;
|
||||
const newValue = this._elementRef.nativeElement.value;
|
||||
|
||||
if (this._previousNativeValue !== newValue) {
|
||||
this._previousNativeValue = newValue;
|
||||
|
||||
Reference in New Issue
Block a user