ViewChild and FromEvent β a Match Made in Angular Heaven
Turn ViewChild
and ContentChild
queries into an RxJS stream.
Installation
npm install @ngneat/from-event
Usage
Use the FromEvent
decorator with ViewChild
or ContentChild
. Note that it expects to get ElementRef
.
import { FromEvent } from '@ngneat/from-event';
@Component({
selector: 'my-btn',
template: `
<button #button>
<ng-content></ng-content>
</button>
`
})
class ButtonComponent implements AfterViewInit {
@FromEvent('click')
@ViewChild('button')
click$: Observable<MouseEvent>;
ngAfterViewInit() {
this.click$.subscribe(console.log);
}
}
You are not limited to use it only inside AfterViewInit
or AfterContentInit
:
@Component({
template: `
<button #plus>+1</button>
<button #minus>-1</button>
<button #reset>Reset</button>
{{ counter$ | async }}
`,
})
export class CounterComponent {
@FromEvent('click')
@ViewChild('plus')
plus$: Observable<MouseEvent>;
@FromEvent('click')
@ViewChild('minus')
minus$: Observable<MouseEvent>;
@FromEvent('click')
@ViewChild('reset')
reset$: Observable<MouseEvent>;
count$ = merge(
this.plus$.pipe(mapTo(1)),
this.minus$.pipe(mapTo(-1))
).pipe(
startWith(0),
scan((acc, curr) => acc + curr)
);
counter$ = this.reset$.pipe(
startWith(null),
switchMap(() => this.count$)
);
}
A common example is using it with switchMap()
:
import { FromEvent } from '@ngneat/from-event';
@Component({
selector: 'my-comp',
template: `
<button #trigger>Trigger</button>
`
})
class MyComponent implements AfterViewInit {
@FromEvent('click')
@ViewChild('trigger')
trigger$: Observable<MouseEvent>;
ngAfterViewInit() {
this.trigger$.pipe(switchMap(() => service.doSomething())).subscribe(result => {
// Do something with the result
});
}
}
Use the FromEvents
decorator with ViewChildren
or ContentChildren
. Note that it expects to get ElementRef
.
import { FromEvents } from '@ngneat/from-event';
@Component({
template: `
<my-btn id="1">Click One</my-btn>
<my-btn id="2">Click Two</my-btn>
<my-btn id="3">Click Three</my-btn>
`
})
class HostComponent implements AfterViewInit, OnDestroy {
@FromEvents('click')
@ViewChildren(ButtonComponent, { read: ElementRef })
clicks$: Observable<MouseEvent>;
ngAfterViewInit() {
this.clicks$.subscribe(e => console.log(e.target));
}
}
Have fun, and don't forget to unsubscribe. If you work with Ivy, you can do it with until-destroy.
Contributors β¨
Thanks goes to these wonderful people (emoji key):
Netanel Basal π» |
Toni Villena π» π‘ |
This project follows the all-contributors specification. Contributions of any kind welcome!