Angular语言 - 如何绑定到嵌套在子组件中两级深处的单选按钮的输入值?



我有一组单选按钮,我已经将它们制作成一个组件,它的父级是一个表单,也是一个组件。父窗体由名称字段、电子邮件字段和一组三个单选按钮问题组成。

parent-form.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);
}
}

单选按钮.组件.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() {}
}

现在我的问题是在ParentFormComponent级别,如何"访问"每组单选按钮的点击值?我尝试将[(ngModel)]="radioSelection1"放在radio-button标签和RadioButtonComponentinput标签上,但它们都不起作用。

我希望能够获取单选按钮的每个选定答案的值,并将其传递给我的后端进行保存。

一种方法是使用ControlValueAccessor.

您可以查看有关此主题的以下文章:

  • 再也不会混淆,以 Angular 形式实现 ControlValueAccessor

  • 对角度形式的彻底探索

另一种方法是利用viewProviders选项。

例如:

父组件.html

<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>

单选按钮.组件.ts

@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;
}

单选按钮组件.html

<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">

使用反应式表单时可以遵循相同的模式,但必须NgForm更改为FormGroupDirective

此解决方案基于viewProviders如何与@Host装饰器协同工作。

例如,NgModel指令的构造函数如下所示:

constructor(
@Optional() @Host() parent: ControlContainer,
/* ... */
) {
super();
this._parent = parent;
/* ... */
}

引自 Angular:嵌套模板驱动表单

主机装饰器使我们有机会从 viewProviders 中获取为主机元素声明的提供程序

在这种情况下,主机元素是<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'
}) { /* ... */ }

源。

如您所见,我们有ControlContainer,可以在viewProviders中访问。

吴运行演示。

最新更新