You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular复用子表单组件相互影响的解决方案咨询

Angular多问题星级评分组件联动问题解决

问题现象

在Angular中通过子组件实现多问题星级评分功能时,点击第二个问题的评分星级会干扰第一个问题的评分显示,需要实现每个问题的评分选择互不影响、各自正确展示所选星级。

相关代码

父组件form.ts

export function defaultForm(): EvaluationPageFormGroup {
  return new FormGroup({
    animation: new FormGroup({
      rate: new FormControl<number | null>(null, [
        Validators.required,
        Validators.max(MAX_STAR_RATE),
      ]),
    }),
    quality: new FormGroup({
      rate: new FormControl<number | null>(null, [
        Validators.required,
        Validators.max(MAX_STAR_RATE),
      ]),
    }),
    interest: new FormGroup({
      rate: new FormControl<number | null>(null, [
        Validators.required,
        Validators.max(MAX_STAR_RATE),
      ]),
    }),
    comment: new FormControl<string | null>(
      null,
      Validators.maxLength(MAX_COMMENT_LENGTH),
    ),
  });
}

父组件模板(原错误版本)

<form [formGroup]="vm.form">
  <tt-evaluation-stars
    [subGroup]="vm.form.controls.firstQuestion"
    [maxStarRate]="vm.maxStarRate"
    [questionNumber]="1"
    [questionLabel]='"Question 1"'
    [questionDescription]='"Description"'
  ></tt-evaluation-stars>

  <tt-evaluation-stars
    [subGroup]="vm.form.controls.secondQuestion"
    [maxStarRate]="vm.maxStarRate"
    [questionNumber]="2"
    [questionLabel]='"Question 2"'
    [questionDescription]='"Description"'
  ></tt-evaluation-stars>
</form>

子组件模板

<div>
  <h3>
    {{questionNumber}} - {{questionLabel}} <span>*</span>
  </h3>
  <p>{{questionDescription}}</p>
  <div [formGroup]="subGroup">
    <fieldset
      class="starRating radiosfield"
      [ngClass]="{'has-checked': subGroup.controls.rate.value !== null}"
    >
      <ng-container *ngFor="let _ of [].constructor(maxStarRate); index as i">
        <input
          class="radio-input starRating-input u-mask"
          type="radio"
          [formControl]="subGroup.controls.rate"
          [value]="i +1"
          [id]="questionNumber + '-' + i +1"
        />
        <label class="starRating-label radio" [for]="questionNumber + '-' + i +1">
          <svg
            class="starRating-label-button"
          >
            [...]
          </svg>
        </label>
      </ng-container>
    </fieldset>
  </div>

  <div class="starRating-subLabel">
    <p>Pas du tout satisfaisant</p>
    <p>Très satisfaisant</p>
  </div>
</div>

问题原因

父组件模板中绑定的firstQuestion、secondQuestion控件,在form.ts的表单定义中并不存在,实际定义的有效控件是animation、quality、interest。这种不匹配导致两个子组件绑定到了同一无效控件,从而出现点击联动的问题。

解决方案

修正父组件模板的表单控件绑定,与form.ts中的定义一一对应:

修正后的父组件模板

<form [formGroup]="vm.form">
  <tt-evaluation-stars
    [subGroup]="vm.form.controls.animation"
    [maxStarRate]="vm.maxStarRate"
    [questionNumber]="1"
    [questionLabel]="'Question 1'"
    [questionDescription]="'Description'"
  ></tt-evaluation-stars>

  <tt-evaluation-stars
    [subGroup]="vm.form.controls.quality"
    [maxStarRate]="vm.maxStarRate"
    [questionNumber]="2"
    [questionLabel]="'Question 2'"
    [questionDescription]="'Description'"
  ></tt-evaluation-stars>
</form>

若需添加第三个问题,直接绑定vm.form.controls.interest即可。每个子组件会关联到独立的FormGroup及内部的rate控件,评分选择就不会互相干扰。

内容的提问来源于stack exchange,提问作者ehtomit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:47:32