首页 > 解决方案 > 如何创建一个角度组件的独立实例

问题描述

我正在尝试在 Angular 中创建一个简单的组件,该组件基本上将枚举映射到单选按钮输入。我已经设置好并且可以正常工作,但是当我将该组件的多个实例放在一个页面上时,我遇到了一些奇怪的问题。我看到的是组件的两个副本相互反应。

这是针对使用 Angular 8 的项目。我已将代码分解为一个托管在此处的小项目,以便您查看发生了什么。托管组件是 app.component.html/.ts,单选按钮组件是 radio.component.html/.ts。

https://stackblitz.com/edit/angular-rcurne

编辑以在此处添加一些实际代码

app.component.html

<app-radio
  [radioSelection]="selectionRadio1"
  (radioSelectionChange)="selectionRadio1 = $event"
></app-radio>
<label>Radio Option Selected: {{ selectionRadio1.toString() }}</label>
<br />
<br />
<app-radio
  [radioSelection]="selectionRadio2"
  (radioSelectionChange)="selectionRadio2 = $event"
></app-radio>
<label>Radio Option Selected: {{ selectionRadio1.toString() }}</label>

radio.component.html

<div class="form-check">
  <input
    class="form-check-input"
    type="radio"
    name="radioInput"
    id="radioInput1"
    [value]="radioSelectionType.Option1"
    [(ngModel)]="radioSelection"
    (ngModelChange)="radioSelectionChangedByUser($event)"
  />
  <label class="form-check-label" for="radioInput1">Option 1</label>
</div>
<div class="form-check">
  <input
    class="form-check-input"
    type="radio"
    name="radioInput"
    id="radioInput2"
    [value]="radioSelectionType.Option2"
    [(ngModel)]="radioSelection"
    (ngModelChange)="radioSelectionChangedByUser($event)"
  />
  <label class="form-check-label" for="radioInput2">Option 2</label>
</div>
<div class="form-check">
  <input
    class="form-check-input"
    type="radio"
    name="radioInput"
    id="radioInput3"
    [value]="radioSelectionType.Both"
    [(ngModel)]="radioSelection"
    (ngModelChange)="radioSelectionChangedByUser($event)"
  />
  <label class="form-check-label" for="radioInput3">Both</label>
</div>

radio.component.ts

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { RadioSelectionType } from './RadioSelectionType'

@Component({
  selector: 'app-radio',
  templateUrl: './radio.component.html'
})
export class RadioComponent implements OnInit {
  @Input() radioSelection: RadioSelectionType;
  @Output() radioSelectionChange = new EventEmitter<RadioSelectionType>();
  public radioSelectionType = RadioSelectionType;

  constructor() { }

  ngOnInit() {
    // If no default was specified via the input, default to Option 3
    if (!this.radioSelection) {
      this.radioSelection = RadioSelectionType.Option3;
    }
  }

  radioSelectionChangedByUser(value: RadioSelectionType) {
    this.radioSelectionChange.emit(this.radioSelection);
  }

}

如上所述,我看到无线电输入相互反应,即使它们是单独的组件。也请随意批评我的编码选择——我是一名最近开始使用 Angular 的 C# 开发人员,所以我可能会遗漏一些关于它如何在 Web 上工作的信息。

标签: javascripthtmlangulartypescriptcomponents

解决方案


无线电组应具有唯一的名称。在您的代码中,所有单选按钮具有相同的名称。

解决方案:将名称作为输入属性传递将解决问题

  ...
  export class RadioComponent implements OnInit {
     @Input() name: string;
     ...

模板:

...
<div class="form-check">
  <input
    class="form-check-input"
    type="radio"
    [name]="name"
...

// app.component.html

<h1>Hello, world!</h1>
<app-radio
name="r1"
  [radioSelection]="selectionRadio1"
  (radioSelectionChange)="selectionRadio1 = $event"
></app-radio>
<label>Radio Option Selected: {{ selectionRadio1.toString() }}</label>
<br />
<br />
<app-radio
name="r2"
  [radioSelection]="selectionRadio2"
  (radioSelectionChange)="selectionRadio2 = $event"
></app-radio>
<label>Radio Option Selected: {{ selectionRadio2.toString() }}</label>

https://stackblitz.com/edit/angular-bxp4my


推荐阅读