events - event - scroll angular 4
Rastreando la posiciĆ³n de desplazamiento y notificando a otros componentes al respecto (2)
Creo que la forma más fácil es que cada componente interesado escuche el evento de desplazamiento.
@Component({
...
// alternative to `@HostListener(...)`
// host: {''(window:scroll)'': ''doSomething($event)''}
})
class SomeComponent {
@HostListener(''window:scroll'', [''$event''])
doSomething(event) {
// console.debug("Scroll Event", document.body.scrollTop);
// see András Szepesházi''s comment below
console.debug("Scroll Event", window.pageYOffset );
}
}
Plunker usando @HostListener()
Insinuación:
bootstrap(MyComponent, [
provide(PLATFORM_DIRECTIVES, {useValue: [TrackScrollDirective], multi:true})]);
hace que la directiva sea universal sin agregarla a todas las directive: [...]
componentes directive: [...]
list.
¿Existe una manera fácil de rastrear la posición de desplazamiento del navegador y notificar al respecto más de un componente individual.
Caso de uso: en un desplazamiento, quiero poder cambiar las clases de varios elementos en la página en función de dónde estoy. En la versión anterior de angular, era algo posible a través del plugin afix (lo mismo para jQuery). Por supuesto, hay una opción de escribir JS desnudo inicializarlo en el inicio de la aplicación y emitir un evento. Suena sucio, y la emisión de eventos es bastante costosa para este tipo de cosas.
¿Cuáles son mis opciones aquí?
ACTUALIZACIÓN (después de sugerencias):
Entonces, esto es lo que intenté:
Creé un componente:
import {Component} from "angular2/core";
@Component({
selector: ''[track-scroll]'',
host: {''(window:scroll)'': ''track($event)''},
template: ''''
})
export class TrackScrollComponent {
track($event) {
console.debug("Scroll Event", $event);
}
}
atributo agregado a la directiva principal de una aplicación:
<priz-app track-scroll>
Y agregó el componente como uno de los proveedores en el componente superior:
import {TrackScrollComponent} from "../../shared/components/track-scroll.component";
@Component({
selector: ''priz-app'',
moduleId: module.id,
templateUrl: ''./app.component.html'',
directives: [ROUTER_DIRECTIVES, SecureRouterOutlet, AppHeader, TrackScrollComponent],
providers: [AuthenticationService]
})
Aún nada...
Otra actualización:
Se movió track-scroll
a uno de los elementos div de la plantilla principal:
<div class="container-fluid" track-scroll>
<div class="row">
<div class="col-md-12">
<app-header></app-header>
<secure-outlet signin="Login" unauthorized="AccessDenied"></secure-outlet>
</div>
</div>
</div>
Y ahora la aplicación se carga con una pantalla completamente vacía. DIVERSIÓN DIVERSIÓN DIVERSIÓN...
SOLUCIÓN FINAL (que funcionó para mí).
- Definir una derectiva:
import {Directive} from "angular2/core";
@Directive({
selector: ''[track-scroll]'',
host: {''(window:scroll)'': ''track($event)''}
})
export class TrackScrollDirective {
track($event: Event) {
console.debug("Scroll Event", $event);
}
}
- Añádalo como una directiva a cualquier lugar que lo use:
directives: [TrackScrollDirective]
- Agregue el atributo a cualquier elemento donde deseemos rastrear el evento:
<div class="col-md-12" track-scroll>
Me vi obligado a resolver esto de manera diferente porque necesitaba ver varios elementos de desplazamiento en la ventana. Creé una directiva para ver la posición de desplazamiento en un elemento:
@Directive({
selector: ''[scroll]''
})
export class ScrollDir {
@Output() setScroll = new EventEmitter();
private scroll: number;
constructor(private el: ElementRef) { }
@HostListener(''scroll'', [''$event''])
scrollIt() { this.scroll = event.srcElement.scrollTop }
reset() { this.el.nativeElement.scrollTop = this.scroll }
}
Luego, en cualquier componente que contenga un elemento de desplazamiento que necesite este elemento, podría @ViewChild
la directiva de esta manera:
@Component({
selector: ''parent'',
template: `
<div class="container" scroll>
// *ngFor=""...
</div>
`
})
export class ParentComp implements AfterViewChecked {
@ViewChild(ScrollDir) scroll: ScrollDir;
ngAfterViewChecked() {
this.scroll.reset()
}
}