Javascript 如何使用“角度8”取消选择“选择元素”中的选定选项元素
我有以下要求:Javascript 如何使用“角度8”取消选择“选择元素”中的选定选项元素,javascript,angular,typescript,angular-reactive-forms,Javascript,Angular,Typescript,Angular Reactive Forms,我有以下要求: 我为select元素mainSelect和subSelect找到了两个FormControl对象,它们是必需的 subSelect根据mainSelect中的值而变化 当main select更改为不包含subSelect中的值时subSelect需要变为无效,因此FormGroup两个FormControl的一部分也变为无效 但是如果包含subSelect中的值,则subSelect需要保留其实际值 (StackBlitz链接后面描述了一个具体示例。) 我的问题解决此要求:
- 我为select元素
和mainSelect
找到了两个subSelect
对象,它们是FormControl
必需的
根据subSelect
中的值而变化mainSelect
- 当
更改为不包含main select
中的值时subSelect
需要变为subSelect
,因此无效
两个FormGroup
的一部分也变为FormControl
无效
- 但是如果包含
中的值,则subSelect
需要保留其实际值subSelect
mainSelect
的值发生变化,并且subSelect
的值未包含subSelect
将取列表的第一个值,而不是变为null
/无效
因此,如果“subSelect”的选定值变为null,并且浏览器中未选择任何值,则解决方案将为
到目前为止我所尝试的:
我试图创建一个组件并实现ControlValueAccessor
接口。我的问题似乎就在这里。我想我真的不明白这是怎么回事
我在上观看了以下视频并阅读了与ControlValueAccessor
相关的文章(,),但仍然无法解决我的问题
这是我代码的一部分:
你也可以在网上找到它
示例
如果在浏览器中MainSelect
具有值thirdMainSelect
和SubSelect
具有值fifthSubSelect
和MainSelect
将其值更改为firstMainSelect
,SubSelect
应无选择值
选择.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;
}
}
@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);
});
}
}
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>
<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>
app.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>
<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>
主选择
再选择
提交
我认为这只是使用价值观。如果有两个数组数据和子数据以及类似
form = new FormGroup({
prop1: new FormControl(),
prop2: new FormControl()
});
简单的
this.form.get("prop1").valueChanges.subscribe(res => {
this.dataService.getData(res).subscribe(data=>{
this.subdata=data;
if (!this.subdata.find(x=>x.value==this.form.get("prop2").value))
this.form.get("prop2").setValue(null);
}).unsubscribe()
});
必须足够了,请看我认为这只是使用价值观。如果有两个数组数据和子数据以及类似
form = new FormGroup({
prop1: new FormControl(),
prop2: new FormControl()
});
简单的
this.form.get("prop1").valueChanges.subscribe(res => {
this.dataService.getData(res).subscribe(data=>{
this.subdata=data;
if (!this.subdata.find(x=>x.value==this.form.get("prop2").value))
this.form.get("prop2").setValue(null);
}).unsubscribe()
});
必须足够了,请参见在尝试仅使用
SelectComponent
解决此问题时,尤其是writeValue
,以下代码完成了此任务:
我将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;
if (!!this.select && !!this.select.nativeElement.value) {
this.writeValue(this.select.nativeElement.value);
this.onChange(this.selected);
}
});
}
ngOnChanges(): void {
this.loadTable();
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
writeValue(value: string): void {
if (!!this.returnedTable && !this.returnedTable.some(item => item.value === value)) {
this.selected = null;
} else {
this.selected = value;
}
}
}
而select.component.html
如下所示:
<select class="form-control" #select (change)="onChange($event.target.value)">
<option hidden *ngIf="!selected" value=""></option>
<option *ngFor="let item of returnedTable" [value]="item.value" [selected]="selected === item.value">{{item.value}}</option>
</select>
{{item.value}}
尝试仅使用SelectComponent
尤其是writeValue
解决此问题一段时间后,以下代码完成了工作:
我将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;
if (!!this.select && !!this.select.nativeElement.value) {
this.writeValue(this.select.nativeElement.value);
this.onChange(this.selected);
}
});
}
ngOnChanges(): void {
this.loadTable();
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
writeValue(value: string): void {
if (!!this.returnedTable && !this.returnedTable.some(item => item.value === value)) {
this.selected = null;
} else {
this.selected = value;
}
}
}
而select.component.html
如下所示:
<select class="form-control" #select (change)="onChange($event.target.value)">
<option hidden *ngIf="!selected" value=""></option>
<option *ngFor="let item of returnedTable" [value]="item.value" [selected]="selected === item.value">{{item.value}}</option>
</select>
{{item.value}}
取消选择选项:-option.selected=false
Angular库的核心是函数反编译,用于
$scope
和嵌套表单,这是一个Angular特性,表明Angular团队不知道如何有效地使用HTML。HTML不允许嵌套表单,那你为什么要强行使用这种语言呢?麻烦太多了。当然,像布拉德利·格林(Bradley Green)这样的前Angular JS经理,你不可能期望有更好的表现。要取消选择选项:-option.selected=false
Angular库的核心是函数反编译,用于
$scope
和嵌套表单,这是一个Angular特性,表明Angular团队不知道如何有效地使用HTML。HTML不允许嵌套表单,那你为什么要强行使用这种语言呢?麻烦太多了。当然,像布拉德利·格林(Bradley Green)这样的前Angular JS经理,你不能期望有更好的表现。只要在主选择值更改时将subselect设置为空白值,你就可以做到这一点,simpleThanks指出了这一点。这是我遗漏的另一个要求。如果mainSelect
的上一个和新值包括subSelect
的实际值,则subSelect
的值需要保持有效。(我希望我试图归档的内容有一半清楚)。我将编辑我的问题以将此要求添加到其中。再次简单,只需浏览子列表并检查所选值是否存在于子列表中。如果是,则不要再次设置该值以保持该值,如果否,则将其设置为“”如果您可以发布解决方案的代码,那就太好了。只要在主选择值更改时将subselect设置为空值,SimpleThat就可以指出这一点。这是我遗漏的另一个要求。如果mainSelect
的上一个和新值包括subSelect
的实际值,则subSelect
的值需要保持有效。(我希望我试图归档的内容有一半清楚)。我将编辑我的问题以将此要求添加到其中。再次简单,只需浏览子列表并检查所选值是否存在于子列表中。如果是,则不要再次设置该值以保持该值,如果否,则将其设置为“”如果您可以发布解决方案的代码,那就太好了。有没有办法不用订阅数据服务,也不用使用select.component.ts
?在我面临这个问题的项目中,select.component.ts
位于另一个模块中,需要进行验证