eje211 eje211 - 12 days ago 105
TypeScript Question

Material2: extending MatInput

I'm trying to make Material 2's

MatInput
listen to a service. I can't do that, of course, so I thought I could extend it instead. But no matter what I do, Angular tells me:


Error: mat-form-field must contain a MatFormFieldControl. Did you
forget to add matInput to the native input or textarea element?


I kept adding parts of the original
MatInput
. Here's what I have now? Am I going down the wrong rabbit hole?

import { Platform} from "@angular/cdk/platform";
import { Directive, ElementRef, Optional, Renderer2 } from "@angular/core";
import { FormGroupDirective, NgControl, NgForm } from "@angular/forms";
import { ErrorStateMatcher, MatInput} from "@angular/material";

import { ReactorService } from "./thrc-react.service";

@Directive({
selector: `input[responsiveMatInput], textarea[responsiveMatInput]`,
exportAs: 'responsiveMatInput',
host: {
'class': 'mat-input-element mat-form-field-autofill-control',
// Native input properties that are overwritten by Angular inputs need to be synced with
// the native input element. Otherwise property bindings for those don't work.
'[attr.id]': 'id',
'[placeholder]': 'placeholder',
'[disabled]': 'disabled',
'[required]': 'required',
'[readonly]': 'readonly',
'[attr.aria-describedby]': '_ariaDescribedby || null',
'[attr.aria-invalid]': 'errorState',
'(blur)': '_focusChanged(false)',
'(focus)': '_focusChanged(true)',
'(input)': '_onInput()',
},
})
export class ResponsiveInputComponent extends MatInput {
constructor(protected _elementRef: ElementRef,
protected _renderer: Renderer2,
protected _platform: Platform,
@Optional() public ngControl: NgControl,
@Optional() protected _parentForm: NgForm,
@Optional() protected _parentFormGroup: FormGroupDirective,
_defaultErrorStateMatcher: ErrorStateMatcher,
reactor: ReactorService, // My service, in case it weren't obvious.
) {
super(_elementRef, _renderer, _platform, ngControl,_parentForm,
_parentFormGroup, _defaultErrorStateMatcher);
reactor.reactor$.subscribe(event => {
console.log('Received.', event);
// My custom code...
}
);

}
}

Answer Source

Add the following the @Directive decorator:

providers: [{provide: MatFormFieldControl, useExisting: ResponsiveInputComponent}]