У меня есть следующие требования:
- Я получил два
FormControl
объекта для элементов select mainSelect
и subSelect
, которые required
. subSelect
изменяется в зависимости от значения mainSelect
. - Когда
mainSelect
изменяется на значение, в которое значение из subSelect
не включено subSelect
необходимостановится invalid
, поэтому FormGroup
, оба из FormControl
являются частью, становится invalid
тоже. - Но если значение из
subSelect
включено, subSelect
необходимо удерживать егофактическое значение.
(конкретный пример описан после ссылки на StackBlitz.)
Моя проблема при решении этого требования:
Еслизначение mainSelect
изменяется и значение subSelect
не включается subSelect
принимает первое значение списка вместо того, чтобы становиться null
/ invalid
.
Таким образом, РЕШЕНИЕ будет, если выбранное значение 'subSelect' станет нулевым, а в браузере не будет выбрано никакого значения.
Что я пробовал до сих пор:
Я пыталсясоздать компонент и реализовать интерфейс ControlValueAccessor
. Кажется, здесь кроется моя проблема. Кажется, я не совсем понимаю, как это работает.
Я смотрел следующее видео на YouTube и читал статьи ( 1 , 2 ) относится к ControlValueAccessor
, но все еще не может решить мою проблему.
Это часть моего кода:
Также вы можете найти его на StackBlitz
Пример
Если в браузере MainSelect
имеет значение thirdMainSelect
, а SubSelect
имеет значение fifthSubSelect
и MainSelect
изменяет его значение на firstMainSelect
SubSelect
, не должно иметь выбранного значения.
select.component.ts
export class SomeObject {
value: string;
parameters: {[parameterName: string]: string} = {};
}
@Component({
selector: "app-select",
templateUrl: "./select.component.html",
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: SelectComponent,
multi: true
}]
})
export class SelectComponent implements ControlValueAccessor, OnChanges {
@ViewChild("select", {static: true}) select: ElementRef;
@Input() tableId: string;
@Input() filter: { [parameterName: string]: string};
returnedTable: SomeObject[];
onChange: (_: any) => void;
onTouched: () => void;
selected: string;
constructor(private tableService: TableService) { }
loadTable(): void {
this.tableService.getTable(this.tableId, this.filter)
.subscribe(table => {
this.returnedTable = table;
});
}
ngOnChanges(): void {
this.loadTable();
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
writeValue(value: string): void {
this.selected = value;
}
}
select.component.html
<select class="form-control" #select (change)="onChange($event.target.value)">
<option *ngFor="let item of returnedTable" [value]="item.value" [selected]="selected === item.value">{{item.value}}</option>
</select>
app.component.ts
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"]
})
export class AppComponent implements OnInit {
form: FormGroup;
containerObject: ContainerObject;
selectedMainValue: string;
constructor(private tableService: TableService,
private formBuilder: FormBuilder) {
}
ngOnInit(): void {
this.tableService.getContainerObject()
.subscribe(containerObject => {
this.containerObject = containerObject;
this.selectedMainValue = containerObject.mainSelect;
this.initForm();
});
}
private initForm(): void {
this.form = this.formBuilder.group({
mainSelect: [this.containerObject.mainSelect, Validators.required],
subSelect: [this.containerObject.subSelect, Validators.required]
});
this.subscribeToMainSelectChanged();
this.subscribeToSubSelectChanged();
}
onSubmit(): void {
if (this.form.valid) {
this.containerObject.mainSelect = this.form.get("mainSelect").value;
this.containerObject.subSelect = this.form.get("subSelect").value;
this.tableService.saveContainerObject(this.containerObject);
}
}
private subscribeToMainSelectChanged() {
this.form.get("mainSelect").valueChanges
.subscribe(mainSelect => {
this.selectedMainValue = mainSelect;
console.log(this.form.status);
});
}
private subscribeToSubSelectChanged() {
this.form.get("subSelect").valueChanges
.subscribe(() => {
console.log(this.form.status);
});
}
}
app.component.html
<div>
<form id="wrapper" [formGroup]="form" (ngSubmit)="onSubmit()">
<div id="left" class="form-group row">
<label for="mainSelect" class="col-form-label col-sm-2">MainSelect</label>
<div class="col-sm-6">
<app-select
id="mainSelect"
formControlName="mainSelect"
[tableId]="'mainSelectTable'"
[filter]="{firstType: 'firstParameter'}"
></app-select>
</div>
</div>
<div id="right" class="form-group row">
<label for="subSelect" class="col-form-label col-sm-2">SubSelect</label>
<div class="col-sm-6">
<app-select
id="subSelect"
formControlName="subSelect"
[tableId]="'firstParameter'"
[filter]="{firstType: 'firstParameter', secondType: selectedMainValue}"></app-select>
</div>
</div>
<p></p>
<button id="button" type="submit">Submit</button>
</form>
</div>