首页 > 解决方案 > 从角度 5 和材料设计 2 中的另一个事件触发事件

问题描述

我想根据另一个单选按钮更改单选按钮的值,但该事件从未触发,并且我没有控制台错误。因此,假设我在位置 5 处单击本田汽车,因此应在表单中的位置 5 处自动选择 Civic 品牌。

我正在使用 Angular 5 和 Material design 2。

这是我的模板:

<mat-list> 
    <mat-list-item *ngFor="let id of ids">
      <mat-radio-group>
        <mat-radio-button name="car" value="honda" id="honda{{id}}" (change)="onChangeCar(id,honda)">Honda</mat-radio-button>
        <mat-radio-button name="car" value="toyota" id="toyota{{id}}" (change)="onChangeCar(id,toyota)">Toyota</mat-radio-button>
      </mat-radio-group>
      <mat-radio-group>
        <mat-radio-button name="brand" value="civic" id="civic{{id}}" (change)="onChangeBrand(id)">Civic</mat-radio-button>
        <mat-radio-button name="brand" value="camry" id="camry{{id}}" (change)="onChangeBrand(id)">Camry</mat-radio-button>
      </mat-radio-group>
   </mat-list-item>
</mat-list>

在控制器中我尝试了这个,但从未触发品牌:

@ViewChildren(MatRadioButton) rbuttons;
rbuttonsList: any[];

// This works
this.rbuttons.filter(x => x.id == 'brand13')[0].checked = true;
this.rbuttons.filter(x => x.id == 'brand131')[0].checked = true;

This give me en error : Cannot read property 'rbuttons' of undefined
// Get the ids that start with brand 13
this.rbuttonsList = this.rbuttons.filter(x => x.id.lastIndexOf('brand13', 0) === 0);
this.rbuttonsList.forEach(function (rbuttonIndex) {
    this.rbuttons.filter(x => x.id == rbuttonIndex.id)[0].checked = true;
  });

标签: angularmaterial-design

解决方案


有几种方法可以在模板中引用具有动态 id 的元素。

元素引用

您可以选择使用 Angular 的 ElementRef 而不是document. 这将为您提供本机元素,但本机版本的 mat-radio-button 上没有选中的属性,因此这不适用于您的目的。

constructor(private elRef:ElementRef) {}

onChangeCar (id, car) {
  if (car == 'honda') {
    let el = this.elRef.nativeElement.querySelector('#civic' + id)
    el.checked = true; // there is no 'checked' property to set 
  }
}

查看儿童

由于 id 是动态的,而不是ViewChild需要显式 id,您可以使用QueryListViewChildren方法。这更好用,因为它使用 Angular 元素包装器,并且可以设置已选中(请参阅控制台上的 rbutton,有一个已选中的属性)。

@ViewChildren(MatRadioButton) rbuttons;

onChangeCar (id, car) {
  if (car == 'honda') {
    let rbutton = this.rbuttons.filter(x => x.id == 'civic' + id);
    rbutton[0].checked = true;
  }
}

按组件属性和模板

您可以通过模板上的选中属性进行设置,引用组件的属性。

brand = ''

onChangeCar (id, car) {
  this.brand = car; 
}
<mat-radio-group>
  <mat-radio-button name="brand" value="civic" id="civic{{id}}" 
    [checked]="brand === 'honda'"
    (change)="onChangeBrand(id)">Civic</mat-radio-button>
  <mat-radio-button name="brand" value="camry" id="camry{{id}}" 
    [checked]="brand === 'toyota'"
    (change)="onChangeBrand(id)">Camry</mat-radio-button>
</mat-radio-group>

这是一个StackBlitz(注意 ViewChildren 和属性方法都是活动的,所以注释掉一个)。


推荐阅读