单击

时间:2018-07-11 09:38:55

标签: angular angular-material2

我需要修改标准Angular Material toggle button component的功能,以便单击活动按钮可使组件返回到没有按钮活动的状态。这有两个步骤:

  • 更新切换组的值
  • 将点击按钮的“ checked”参数更改为false

我尝试了几种方法,例如

模板:

<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;
}

但是,这不会更新按钮的“ 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;

4 个答案:

答案 0 :(得分:6)

一个简单的通用解决方案不需要使用每个按钮上的事件或单击事件,也不需要ViewChildren或对值进行硬编码检查,可以在多种模式下使用按钮切换并通过以下方式管理选择组更改事件。更改事件为您提供了所需的一切,因此无需直接访问子组件:

<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上。

答案 1 :(得分:0)

解决方案是在切换组上使用单击事件,在组上使用更改事件,或在单个按钮上使用单击事件。

这比在每个按钮上都具有单击事件要干净得多,并且可以捕获每次交互,而不管切换组的值在正常情况下是否会发生变化,因此该功能可以根据需要对再次单击活动按钮的情况做出响应。

$ event和每个切换按钮上的数据属性可用于标识已单击组中的哪个按钮,因此与非活动按钮的交互将按常规处理。

模板:

<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

}

答案 2 :(得分:0)

根据源代码(^ 6.4.1),{{1}的change事件总是在鼠标单击时触发:

https://github.com/angular/material2/blob/6.4.7/src/lib/button-toggle/button-toggle.ts#L461

我们可以订阅所有切换按钮(或仅订阅那些我们希望取消选中的按钮):

MatButtonToggle

我们可以为这些事件添加一个简单的处理程序,并添加一个存储状态的字段:

<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>

This example is on Stackblitz

另一种实现方式:

我们可以绑定private _activeValue = ""; onChange(event, group) { if (this._activeValue === event.value) { // make unchecked group.value = ""; this._activeValue = ""; } else { this._activeValue = event.value; } }

value

答案 3 :(得分:0)

这是另一种解决方案。请注意,change 事件发生在 click 事件之前。

组件

toggleChanged: boolean;

onChange() {
  this.toggleChanged = true;
}

onClick(group: MatButtonToggleGroup) {
  if (!this.toggleChanged) group.value = null;
  this.toggleChanged = false;
}

模板

<mat-button-toggle-group [(value)]="myValue" #group="matButtonToggleGroup"
    (change)="onChange()" (click)="onClick(group)">
    <mat-button-toggle *ngFor="let item of items" [value]="item.value">
        {{ item.name }}
    </mat-button-toggle>
</mat-button-toggle-group>