How can I programmatically trigger ripple effect o

2019-07-27 03:55发布

问题:

In Angular material you have the lovely ripple effect on a lot of the components. When you click on a mat-list-item the ripple effect happens.

Now with buttons and many other components you can trigger the ripple effect with button.ripple.launch(...) but with mat-list-item I see no such functionality. I'd like to be able to do it to inform users of changes made to the list.

Does anyone know of a workaround? I've tried dispatching 'click' from the MatListItem's _getHostElement(), but to no avail.

EDIT

Thanks to everybody who's helped out! I think in the end I'll just design my own list component that gives me access to its MatRipple directive. I've forked pr41's stackblitz to have the situation be similar to what I have (a list generated with *ngFor) and if anyone knows what to put here:

this.listChildren.map((item: MatListItem) => {
  // item is the MatListItem. How do I access its ripple directive?
});

that would be great!

The Fork: https://stackblitz.com/edit/angular-mmjda4-ssoajs?file=app%2Flist-overview-example.ts

回答1:

As of recent versions of Material, there is now a Ripples module (docs here) that allow for the customization and programmatic triggering of ripples in a component, such as mat-list-item.

Programmatic triggering involves the following: First, we make our list and attach the matRipple directive. In my example, I'm using a button click to trigger the ripple, so an event handler has been added as well:

<mat-list role="list" matRipple>
  <mat-list-item role="listitem">Item 1</mat-list-item>
  <mat-list-item role="listitem">Item 2</mat-list-item>
  <mat-list-item role="listitem">Item 3</mat-list-item>
</mat-list>
<button mat-raised-button color="accent" (click)="triggerRipple()">Trigger Ripple</button>

Within the component, we grab the matRipple using ViewChild, allowing us to call launch() on the ripple to trigger the actual ripple effect:

@ViewChild(MatRipple) ripple: MatRipple;

triggerRipple() {
  this.ripple.launch({centered: true});
}

Here's a stackblitz showing this sample in action; click the button to cause a ripple in the mat-list. Naturally, you can move the matRipple directive to any component if you'd like the ripple effect applied to something else. Take a look at the docs for more configuration options available.



回答2:

You can try dynamic template reference variable. It works to me.

import { MatRipple } from '@angular/material/core';

export class FooComponent {
    @ViewChildren(MatRipple) rippleList: QueryList<MatRipple>;

    ngAfterViewInit() {
        let ripples = this.rippleList.toArray()
        ripples.forEach(res => {
                // res is the instance of each matRipple
        })
    }

}


But It confused to me that I can use it perfect in my project but I can't reappear it in stackblitz:(