问题
I am trying to get the selectedValue of the radio button and pass it as true with the radio text. selectedValue to be sent as true if Choice 1 is selected else false. And selectedValue to be sent as true if Choice 2 is selected, else false. I could not set it to true. Was wondering if anyone has done this before?
https://stackblitz.com/edit/angular-xfrezb
回答1:
First of all, always include the relevant code in your question as code blocks, since links tend to die over time...
But as for your question, since you are dealing with several questions and dynamic value
, I would pass the current formArray components
and the current answer
. You would need to first then set all form controls selectedValue
as false
, since otherwise toggling the radio buttons each would eventually become true
of clicking every of them. So after first setting all as false
then just set the chosen radio button as true
. So do something like this:
<div *ngIf="question.controls.type.value === 'radio'">
<p>{{ question.controls.label.value }}</p>
<div formArrayName="component">
<div *ngFor="let answer of question.controls.component.controls;
let j = index" [formGroupName]="j">
<label>
<input type="radio" name="radio-stacked"
(click)="updateSelection(question.controls.component.controls, answer)">
<span>{{ answer.value.value }}</span>
</label>
</div>
</div>
</div>
Then your updateSelection
method:
updateSelection(formArr, answer) {
formArr.forEach(x => {
x.controls.selectedValue.setValue(false);
});
answer.controls.selectedValue.setValue(true);
}
Your forked StackBlitz
PS, what you could of course consider doing, is not to have all choices in your form object, but just add the value of the radio button you have chosen.
回答2:
You are mixing the presentation view and the value of the form. I think that it's better separate the concepts. We can use formObj to create the presentation, and callbackForm for the value. See the comments in the code
//app.main.html
<form [formGroup]="callbackForm" (submit)=submit(callbackForm)>
<div>
<div formArrayName="componentDetails">
<div *ngFor="let question of callbackForm.controls.componentDetails.controls; let i = index;" [formGroupName]="i">
<div class="row">
<div class="col-md-12 panel-group panel-group--compressed">
<div class="panel panel--default">
<fieldset>
<!--see that we create the "view of the form using formObj.componentDetails--!>
<div class="row" *ngIf="formObj.componentDetails[i].type === 'radio'">
<div class="col-md-12">
<p>{{ formObj.componentDetails[i].label }}</p>
<p>{{ formObj.componentDetails[i].cpv }}</p>
<!-- we iterate throught "formObj.componentDetails[i].component -->
<!-- again, we are using formObj to the "view" -->
<div *ngFor="let answer of formObj.componentDetails[i].component; let j = index">
<label class="radio radio--alt radio--stacked">
<span class="radio__input"></span>
<span class="radio__label">{{ answer.value }}</span>
</label>
<!--We have a input with name=formObj.componentDetails[i].cpv -->
<!--it's necesary enclose between {{ }} the name -->
<input type="radio" formControlName="{{formObj.componentDetails[i].cpv}}" [value]="answer.selectedValue">
</div>
</div>
</div>
</fieldset>
</div>
</div>
</div>
</div>
</div>
</div>
<button type="submit">send</submit>
</form>
<pre>{{callbackForm.value | json}}</pre>
//app-main.component
@Component({
selector: 'app-app-main',
templateUrl: './app-main.component.html'
})
export class AppMainComponent {
constructor(private _formBuild: FormBuilder) {}
ngOnInit() {
this.loadObservableForm();
}
public callbackForm: FormGroup;
formObj = {
"componentDetails": [{
"component": [{
"value": "Choice 1",
"selectedValue": true
}, {
"value": "Choice 2",
"selectedValue": false
}],
"cpv": "name1", //<--we use this to create the name of the fileld
"label": "Description of Problem",
"type": "radio",
"mandatory": true
}]
};
loadObservableForm() {
this.callbackForm = this._formBuild.group({
componentDetails: this._formBuild.array([])
});
this.addComponentDetails();
}
addComponentDetails() {
const control = <FormArray>this.callbackForm.controls.componentDetails;
this.formObj.componentDetails.forEach(x => {
control.push(this.addControl(x));
});
}
addControl(x) {
//we create a group control with a control with a name "x.cpv"
const group = this._formBuild.group({});
group.addControl(x.cpv,new FormControl());
return group;
}
We have a callbackForm in the way "componentDetails": [{"name1": false},{"name2":value2}...]. So, in the submit we can do some like
submit(form)
{
if (form.valid)
{
let response:any={}
for (let control of form.value.componentDetails)
response={...response,...control}
console.log(response);
}
}
来源:https://stackoverflow.com/questions/48471846/how-to-get-selected-value-of-radio-in-reactive-form