angular - 从角度 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;
});
解决方案
有几种方法可以在模板中引用具有动态 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 和属性方法都是活动的,所以注释掉一个)。