Я пытаюсь создать упаковку выпадающего меню Material (mat-select dropdown), которая будет работать с formControlName. Может кто-нибудь опубликовать свой Stackblitz, если он есть в их библиотеке? Не стесняйтесь начинать с нуля и создавать собственный ответ, независимо от того, что отвечает требованиям.
Требования:
1) Необходимо работать с formControlName. У нас есть родительский компонент form с formBuilder / и его валидаторами, которые пытаются ссылаться на эту дочернюю оболочку. Родительский компонент formbuilder также имеет много других полей формы, как и типичный сценарий ios.
2) Необходимо отображать ошибку красного цвета как недопустимую, если данные не соответствуют требованиям родительских валидаторов FormBuilder.
3) а) Должен работать не только с formControlName / patchValue (patchValue должен работать со всем классом); б) при желании также, если кто-то помещает данные в номер идентификатора @Input () SelectedValueId. может работать с двумя
Попытка заставить это работать, но пока не удалось. У кого-нибудь есть код, чтобы это исправить?
Нужен рабочий стек, для успешного ответа
В этом случае Id is sourceOfAddressId
export class SourceOfAddressDto implements ISourceOfAddressDto {
sourceOfAddressId: number | undefined; // should work with this Id
sourceOfAddressCode: string | undefined;
sourceOfAddressDescription: string | undefined;
Машинопись:
@Component({
selector: 'app-address-source-dropdown',
templateUrl: './address-source-dropdown.component.html',
styleUrls: ['./address-source-dropdown.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AddressSourceDropdownComponent),
multi: true
}
]
})
export class AddressSourceDropdownComponent implements OnInit, OnChanges {
dataList: any[] = [];
@Input() Label = 'Address Source';
@Input() sourceOfAddressDefaultItem: SourceOfAddressDto = SourceOfAddressDefault;
@Input() selectedSourceOfAddress: any;
@Input() TxtValue = 'sourceOfAddressId';
@Input() TxtField = 'sourceOfAddressDescription';
@Input() Disabled: boolean;
@Input() valuesToExclude: number[] = [];
@Input() Hint = '';
@Input() styles: string;
@Input() defaultSourceOfAddressCode: any;
@Output() addressSourceChange = new EventEmitter<any>();
private _selectedValueId: number;
@Input() set selectedValueId(value: number) {
this._selectedValueId = value;
let outputData: any;
if (this.selectedValueId == this.sourceOfAddressDefaultItem[this.TxtValue]) {
outputData = null;
} else {
outputData = this.dataList.find(x => x[this.TxtValue] == this.selectedValueId);
}
this.onChange(outputData);
}
get selectedValueId(): any {
return this._selectedValueId;
}
@Input() errors: any = null;
disabled: boolean;
control: FormControl;
writeValue(value: any) {
this.selectedValueId = value ? value : '';
}
onChange = (_: any) => { };
onTouched: any = () => { };
registerOnChange(fn: any) { this.onChange = fn; }
registerOnTouched(fn: any) { this.onTouched = fn; }
setDisabledState(isDisabled) { this.disabled = isDisabled; }
constructor(
public injector: Injector,
private AddressService: AddressServiceProxy,
) { }
ngOnInit() {
this.loadDataList();
}
ngOnChanges() { }
loadDataList() {
this.AddressService.getSourceOfAddressAll().subscribe(res => {
this.dataList = res.body.filter(q => q.sourceOfAddressId !== -1);
});
}
}
HTML:
<div class="dropdown-cont">
<mat-form-field appearance="outline">
<mat-label>{{Label}}</mat-label>
<mat-select
disableOptionCentering
[disabled]="Disabled"
[ngStyle]="styles"
(ngModelChange)="selectedValueId=$event"
required>
<mat-option [value]="sourceOfAddressDefaultItem[TxtValue]">{{sourceOfAddressDefaultItem[TxtField]}}</mat-option>
<mat-option *ngFor="let item of dataList" [value]="item[TxtValue]">
{{item[TxtField]}}
</mat-option>
</mat-select>
<mat-hint>{{Hint}}</mat-hint>
</mat-form-field>
</div>
- также, надеюсь, работает со значениями по умолчанию, даже если API иногда отстает, и значение по умолчанию вставляется первым в @Input SelectedValueId