我有一个自定义单选列表,每个控件的控件名称不同(这些控件是html中的复选框)。我认为是从这些复选框的列表(输入名称)中可以选择的一个,我可以这样做(在ngOnInit中) :
formGroup
.get('ChildGroup')
.valueChanges.pipe(
startWith(formGroup.get('ChildGroup').getRawValue()),
pairwise(),
)
.subscribe(([oldState, newState]) => {
console.log(oldState, newState)
// List of radio checkboxes
const radioInputs = [
'childName1', 'childName2', 'childName3', 'childName4',
];
// Find changed value
const updatedElementName = radioInputs.find(
elem => oldState[elem] !== newState[elem],
);
// Set true only for input which is changed
radioInputs.forEach(input => {
formGroup
.get('ChildGroup')
.get(input)
.setValue(
updatedElementName === input, { emitEvent: false },
);
});
});
问题很奇怪,因为单击复选框后,我从日志中收到了这样的数据:
// First click on childName2 (childName1 unchecked) - correct, expected
oldState.childName1 // true
oldState.childName2 // false
newState.childName1 // true
newState.childName2 // true
// Second click on childName1 (childName1 and childName2 unchecked)
oldState.childName1 // true
oldState.childName2 // true
newState.childName1 // true
newState.childName2 // true
第二次单击中的
Stackblitz出现此错误:
https://stackblitz.com/edit/angular-q9ppdt
如果我的描述不清楚,请告诉我。
谢谢!
答案 0 :(得分:2)
这可能是一个简单的解决方案,只需为每个控件订阅值更改并翻转另一个控件值
this.formGroup.get('control1').valueChanges.subscribe(value => {
this.formGroup.get('control2').setValue(!value, { emitEvent: false })
})
this.formGroup.get('control2').valueChanges.subscribe(value => {
this.formGroup.get('control1').setValue(!value, { emitEvent: false })
})
已更新!?? 与上述相同的想法的基础,但作为控件数组的动态订阅基础
以防我有此控件列表
radioInputs = [
'control1', 'control2', 'control3', 'control4', 'control5'
];
为每个表单控件订阅,每次选中的任何控件都会重置其他控件
this.radioInputs.forEach(control => {
this.formGroup.get(control).valueChanges.subscribe(value => {
if (value) {
this.resetOthers(control);
}
})
});
重置方法
resetOthers(currentControl) {
this.radioInputs.filter(control => control !== currentControl).forEach(control => {
this.formGroup.get(control).setValue(false, { emitEvent: false })
})
}
答案 1 :(得分:1)
这本身并不能回答您问题的技术性,但是我在这里https://stackblitz.com/edit/angular-s1vj53达到了您想要达到的目的
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { mergeMap, pairwise, startWith, take } from 'rxjs/operators';
interface RadioControl {
title: string;
initialValue: boolean;
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
name = 'Angular';
formGroup: FormGroup
public controls: RadioControl[] = [
{
title: 'control1',
initialValue: true
},
{
title: 'control2',
initialValue: false
},
{
title: 'control3',
initialValue: false
},
{
title: 'control4',
initialValue: false
}
]
constructor(
private fb: FormBuilder
) {
}
handleInputClick(controlName: string): void {
// remove this if block if you wish not allow all blank inputs and always have one selected
// This allows to unselect all
if (this.formGroup.get(controlName).value) {
this.formGroup.get(controlName).setValue(false);
return;
}
Object.keys(this.formGroup.controls).forEach((e: string) => {
this.formGroup.get(e).setValue(e === controlName);
});
}
ngOnInit() {
const groupInitObj = {}
this.controls.forEach((e: RadioControl) => {
groupInitObj[e.title] = this.fb.control(e.initialValue);
});
this.formGroup = this.fb.group(groupInitObj);
}
}
<form [formGroup]="formGroup">
<input *ngFor="let control of controls" (click)="handleInputClick(control.title)" type="checkbox" [formControlName]="control.title">
</form>