简体   繁体   English

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

[英]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标签和RadioButtonComponentinput标签上,但它们都不起作用。

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:您可以查看有关此主题的这些文章:

Another approach would be to leverage the viewProviders option.另一种方法是利用viewProviders选项。

For example:例如:

parent.component.html父组件.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>

radio-buttons.component.ts单选按钮.component.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;
}

radio-buttons.component.html单选按钮.component.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">

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'
}) { /* ... */ }

Source . 来源

As you can see, we have the ControlContainer , which can be accessed in viewProviders .如您所见,我们有ControlContainer ,可以在viewProviders中访问它。

ng-run demo . ng-运行演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 function 从父级传递给深层嵌套子级,并将@input 值用于 Angular 8 中传递的 function 中? - How to pass a function from a parent to a deep nested child and use an @input value into the passed function in Angular 8? 如何使用Angular 4中的Router模块将父组件输入值传递给两个子组件? - How do you pass a parent components input value to two child components using the Router module in Angular 4? 如何绑定到angular2 beta 6中的单选按钮 - How to bind to radio buttons in angular2 beta 6 Angular2 ReactiveFormsControl:如何绑定单选按钮? - Angular2 ReactiveFormsControl: how to bind radio buttons? 角度4:将两个具有相同值的HTML组件绑定 - Angular 4: Bind two HTML components with the same value 如何在Angular中深入获取值3个组件 - How to capture a value 3 components deep in Angular 如何将数据绑定到Angular 2中的多个嵌套组件? - How bind data to multiple nested components in Angular 2? 将搜索输入值发射到Angular 2中的子组件 - Emit search input value to child components in Angular 2 在 Angular 中绑定两个子组件的输入和输出的最佳方法 - Best way to bind inputs and outputs of two child components in Angular angular 2 如何绑定两个组件的行为 - angular 2 how to bind two components behavior
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM