[英]Angular - how to bind to the input value of radio buttons that are nested two levels deep in child components?
I have a set of radio buttons that I've made into a component and its parent is a form which is also a component.我有一组已制成组件的单选按钮,其父级是一个表单,也是一个组件。 The parent form consists of a name field, an email field, and a set of three radio button questions.
父表单由一个名称字段、一个 email 字段和一组三个单选按钮问题组成。
parent-form.component.ts父窗体.component.ts
@Component({
selector: 'parent-form',
template: `
<form #myform="ngForm" (ngSubmit)="save(myform)">
<label>Name</label>
<input type="text" id="name" name="name" [(ngModel)]="name" />
<label>Email</label>
<input type="text" id="email" name="email" [(ngModel)]="email" />
<label>Radio Question 1</label>
<radio-buttons [radioText]="radioButtonsText[0]" [radioId]="0"></radio-buttons>
<label>Radio Question 2</label>
<radio-buttons [radioText]="radioButtonsText[1]" [radioId]="1"></radio-buttons>
<label>Radio Question 3</label>
<radio-buttons [radioText]="radioButtonsText[2]" [radioId]="2"></radio-buttons>
</form>
`
})
export class ParentFormComponent implement OnInit {
name: string = "";
email: string = "";
radioSelection1: number = 0;
radioSelection2: number = 0;
radioSelection3: number = 0;
radioButtonText = [
['Very Bad', 'Bad', 'Neutral', 'Good', 'Very Good'],
['None', 'A Little', 'Somewhat', 'Often', 'Frequent'],
['Very Worried', 'A bit worried', 'Neutral', 'generally not worried', 'not worried at all']
];
ngOnInit() {}
save(form: NgForm) {
console.log(form.value);
}
}
radio-buttons.component.ts单选按钮.component.ts
@Component({
selector: 'radio-buttons',
template: `
<div>
<label>
<input type="radio" name="radio + {{ radioId }}" id="option1" value="0" />
{{ radioText[0] }}
</label
<label>
<input type="radio" name="radio + {{ radioId }}" id="option2" value="1" />
{{ radioText[1] }}
</label
<label>
<input type="radio" name="radio + {{ radioId }}" id="option3" value="2" />
{{ radioText[2] }}
</label
<label>
<input type="radio" name="radio + {{ radioId }}" id="option4" value="3" />
{{ radioText[3] }}
</label
<label>
<input type="radio" name="radio + {{ radioId }}" id="option5" value="4" />
{{ radioText[4] }}
</label
</div>
`
})
export class RadioButtonComponent {
@Input() radioText = [];
@Input() radioId = '';
constructor() {}
}
Now my question is at the ParentFormComponent
level, how do "access" the clicked value of each set of radio buttons?现在我的问题是在
ParentFormComponent
级别,如何“访问”每组单选按钮的点击值? I tried putting [(ngModel)]="radioSelection1"
on the radio-button
tag and on the input
tag of the RadioButtonComponent
but neither of them work.我尝试将
[(ngModel)]="radioSelection1"
放在radio-button
标签和RadioButtonComponent
的input
标签上,但它们都不起作用。
I want to be able to get the values of each of selected answer of the radio buttons and pass that on to my backend for saving.我希望能够获取单选按钮的每个选定答案的值,并将其传递到我的后端进行保存。
One approach would be to use ControlValueAccessor
.一种方法是使用
ControlValueAccessor
。
You could check out these articles on this topic:您可以查看有关此主题的这些文章:
Never again be confused when implementing ControlValueAccessor in Angular forms 在 Angular forms 中实现 ControlValueAccessor 时再也不会感到困惑
Another approach would be to leverage the viewProviders
option.另一种方法是利用
viewProviders
选项。
For example:例如:
<form #f="ngForm">
<input ngModel name="test" type="text">
<app-radio-buttons ctrlName="radioCtrl"></app-radio-buttons>
</form>
<p>
Form values: {{ f.value | json }}
</p>
@Component({
selector: 'app-radio-buttons',
templateUrl: './radio-buttons.component.html',
styleUrls: ['./radio-buttons.component.css'],
viewProviders: [
{
provide: ControlContainer,
useExisting: NgForm,
}
]
})
export class RadioButtonsComponent implements OnInit {
@Input() ctrlName: string;
}
<h3>radio btn component</h3>
value1: <input ngModel [name]="ctrlName" type="radio" value="1">
value2: <input ngModel [name]="ctrlName" type="radio" value="2">
<!-- Setting a default value -->
value3: <input ngModel="3" [name]="ctrlName" type="radio" value="3">
You can follow the same pattern when working with Reactive Forms , but you'll have to change NgForm
to FormGroupDirective
.使用Reactive Forms时,您可以遵循相同的模式,但您必须将
NgForm
更改为FormGroupDirective
。
This solution is based on how viewProviders
works together with the @Host
decorator.此解决方案基于
viewProviders
如何与@Host
装饰器一起工作。
For instance, this is how the NgModel
directive's constructor looks like:例如,这就是
NgModel
指令的构造函数的样子:
constructor(
@Optional() @Host() parent: ControlContainer,
/* ... */
) {
super();
this._parent = parent;
/* ... */
}
Quoted from Angular: Nested template driven form引自Angular:嵌套模板驱动表单
Host decorator gives us the opportunity to get a provider from viewProviders declared for host element
宿主装饰器让我们有机会从为宿主元素声明的 viewProviders 中获取提供者
The host element in this case is the <form>
element:在这种情况下,宿主元素是
<form>
元素:
export const formDirectiveProvider: any = {
provide: ControlContainer,
useExisting: forwardRef(() => NgForm)
};
@Directive({
selector: 'form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]',
providers: [formDirectiveProvider],
host: {'(submit)': 'onSubmit($event)', '(reset)': 'onReset()'},
outputs: ['ngSubmit'],
exportAs: 'ngForm'
}) { /* ... */ }
As you can see, we have the ControlContainer
, which can be accessed in viewProviders
.如您所见,我们有
ControlContainer
,可以在viewProviders
中访问它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.