我需要修改标准Angular Material toggle button component的功能,以便单击活动按钮可将组件返回到没有按钮处于活动状态的状态。这有两个步骤:
我尝试了几种方法,例如
模板:
<mat-button-toggle-group #group="matButtonToggleGroup">
<mat-button-toggle #no_btn value="no" (click)="update_toggle(group,no_btn)">No</mat-button-toggle>
<mat-button-toggle #yes_btn value="yes" (click)="update_toggle(group,yes_btn)">Yes</mat-button-toggle>
</mat-button-toggle-group>
JS:
update_toggle(group,button){
if(group.value==""){
group.value = button.value;
}
else
{
group.value = "";
}
button.checked=!button.checked;
}
但这不会更新按钮的“已检查”值,我猜是因为update_toggle()设置的组值与单击按钮的用户操作冲突。
唯一有效的方法是:
<mat-button-toggle-group #group="matButtonToggleGroup">
<mat-button-toggle #no_btn value="no" (click)="update_toggle(group,no_btn)" (click)="group.value=='no' ? checked=false : checked=false">No</mat-button-toggle>
<mat-button-toggle #yes_btn value="yes" (click)="update_toggle(group,yes_btn)" (click)="group.value=='yes' ? checked=false : checked=false">Yes</mat-button-toggle>
</mat-button-toggle-group>
但是单个按钮上的两个单击事件感觉非常黑客,特别是因为第二次点击中的三元组与其本能应该是相反的。
有关更好方法的任何建议吗?
我试过了:
@ViewChildren('no_btn') no_btn: ElementRef;
然后:
this.no_btn['_results'][k]['_inputElement']['nativeElement']['checked']=false;
但结果似乎与传递函数中的按钮引用没有任何不同;再次单击该按钮不会取消选中它。禁用确实有效,所以我认为我的代码是正确的:
this.no_btn['_results'][k]['_inputElement']['nativeElement']['disabled']=true;
一个简单的通用解决方案,不需要在每个按钮上使用事件或完全单击事件,并且不需要ViewChildren或硬编码值检查,是使用按钮在多种模式下切换并通过组更改管理选择事件。 change事件为您提供了所需的一切,因此无需直接访问子组件:
<mat-button-toggle-group multiple (change)="toggleChange($event)">
<mat-button-toggle value="no">No</mat-button-toggle>
<mat-button-toggle value="yes">Yes</mat-button-toggle>
</mat-button-toggle-group>
toggleChange(event) {
let toggle = event.source;
if (toggle) {
let group = toggle.buttonToggleGroup;
if (event.value.some(item => item == toggle.value)) {
group.value = [toggle.value];
}
}
}
这是在Stackblitz。
解决方案是在切换组上使用单击事件,而不是在组上使用更改事件,或单击各个按钮上的事件。
这比在每个按钮上点击事件更清晰,并且捕获每次交互,无论切换组的值是否会在正常行为下发生变化,因此该功能可以根据需要响应再次单击活动按钮的情况。
每个切换按钮上的$ event和data属性可用于标识组中的哪个按钮被单击,因此与非活动按钮的交互将照常处理。
模板:
<mat-button-toggle-group #group="matButtonToggleGroup" (click)="update_selected($event,group,k)">
<mat-button-toggle #exclude value="exclude" data-toggle="exclude"><i class="material-icons">remove</i></mat-button-toggle>
<mat-button-toggle #include value="include" data-toggle="include"><i class="material-icons">add</i></mat-button-toggle>
</mat-button-toggle-group>
JS:
@ViewChildren('exclude') exclude: ElementRef;
@ViewChildren('include') include: ElementRef;
...
update_selected(event, group, index){
if(group.value=='exclude' && event['srcElement']['offsetParent']['dataset']['toggle']=='exclude')
{
this.exclude['_results'][index].checked=false;
group.value="";
return;
}
if(group.value=='include' && event['srcElement']['offsetParent']['dataset']['toggle']=='include')
{
this.include['_results'][index].checked=false;
group.value="";
return;
}
// Group was unselected before click, or non-active toggle button was clicked
}
根据源代码(^ 6.4.1),change
事件(MatButtonToggle
)在鼠标点击时始终触发:
https://github.com/angular/material2/blob/6.4.7/src/lib/button-toggle/button-toggle.ts#L461
我们可以订阅所有切换按钮(或只包含我们想要取消选中的那些按钮):
<mat-button-toggle-group #group="matButtonToggleGroup">
<mat-button-toggle value="no" (change)="onChange($event, group)">No</mat-button-toggle>
<mat-button-toggle value="yes" (change)="onChange($event, group)">Yes</mat-button-toggle>
</mat-button-toggle-group>
我们可以为这些事件添加一个简单的处理程序,并为存储状态的字段添加:
private _activeValue = "";
onChange(event, group) {
if (this._activeValue === event.value) {
// make unchecked
group.value = "";
this._activeValue = "";
} else {
this._activeValue = event.value;
}
}
另一个实现:
我们可以绑定value
。
<mat-button-toggle-group [value]="_activeValue">
<mat-button-toggle value="no" (change)="onChange($event)">No</mat-button-toggle>
<mat-button-toggle value="yes" (change)="onChange($event)">Yes</mat-button-toggle>
</mat-button-toggle-group>
public _activeValue = "";
onChange(event, group) {
if (this._activeValue === event.value) {
// make unchecked
this._activeValue = "";
} else {
this._activeValue = event.value;
}
}