hostlistener event events scroll angular

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

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í).

  1. 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); } }

  1. Añádalo como una directiva a cualquier lugar que lo use:

directives: [TrackScrollDirective]

  1. 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() } }