跟踪滚动位置并通知其他组件 [英] Tracking scroll position and notifying other components about it

查看:175
本文介绍了跟踪滚动位置并通知其他组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



使用案例:在滚动条上,我想要能够根据我在哪里更改页面上各种元素的类。在以前版本的角度,有可能通过afix插件(与jQuery相同)。当然,有一个选择是在应用程序启动时初始化它,并发出一个事件。听起来很脏,事件发射对于这种类型的事情来说是相当昂贵的。



我在这里有什么选择?






更新(建议后):



所以,这是我试过的:



我从angular2 / core创建了一个组件:

  import {Component} 

@Component({
selector:'[track-scroll]',
host:{'(window:scroll)':'track($ event)'}
template:''
})

export class TrackScrollComponent {
track($ event){
console.debug(Scroll Event,$事件);
}
}

添加属性到一个应用程序的主要指令: / p>

 < priz-app track-scroll> 

并将该组件作为顶级组件中的提供者之一添加:

$ b $来自../../shared/components/track-scroll.component的b

  import {TrackScrollComponent}; 

@Component({
selector:'priz-app',
moduleId:module.id,
templateUrl:'./app.component.html'
指令:[ROUTER_DIRECTIVES,SecureRouterOutlet,AppHeader,TrackScrollComponent],
providers:[AuthenticationService]
})

仍然没有...



另一个更新:



code> track-scroll 到主模板的div元素之一:

  < div class =container-fluidtrack-scroll> 
< div class =row>
< div class =col-md-12>
< app-header>< / app-header>
< secure-outlet signin =Loginunauthorized =AccessDenied>< / secure-outlet>
< / div>
< / div>
< / div>

现在应用程序加载完全空的屏幕。
FUN FUN FUN ...



FINAL SOLUTION(对我有用)。


  1. 定义一个derective:





 从angular2 / core导入{Directive}; 

@Directive({
selector:'[track-scroll]',
host:{'(window:scroll)':'track($ event)'}
})

导出类TrackScrollDirective {
track($ event:Event){
console.debug(Scroll Event,$ event);
}
}




  1. 将其作为指令添加到使用它的任何地方:





 指令:[TrackScrollDirective] 




  1. 添加属性到我们要跟踪事件的任何元素:





 < div class =col-md-12track-scroll> 


解决方案

我认为最简单的方法是每个感兴趣的组件监听滚动事件。

  @Component({
...
//替代`@HostListener(...)`
// host:{'(window:scroll)':'doSomething($ event)'}
})
class SomeComponent {
@HostListener('window:scroll',['$ event'])
doSomething(event){
// console.debug(Scroll事件,document.body.scrollTop);
//看到AndrásSzepesházi的评论在
console.debug(Scroll Event,window.pageYOffset);
}
}

plunker



Plunker使用 @HostListener()



提示:

  bootstrap MyComponent,[
提供(PLATFORM_DIRECTIVES,{useValue:[TrackScrollDirective],multi:true})]);

使该指令普遍不添加到每个组件指令:[.. 。] 列表。


Is there an easy way to track browser scroll position and notify about it more than a single component.

Use case: On a scroll, I want to be able to change classes of various elements on the page based on where I am. In previous version of angular, it was somewhat possible through afix plugin (same for jQuery). Of course, there is an option of writing bare JS initialize it on application start and emit an event. Sounds dirty, and event emission is pretty expensive for this type of thing.

What are my options here?


UPDATE (after suggestions):

So, here is what I tried:

I created a component:

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

added attribute to the main directive of an app:

<priz-app track-scroll>

And added the component as one of the providers in the top component:

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]
})

Still nothing...

Another Update:

Moved track-scroll to one of the div elements of the main template:

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

And now the app loads with completely empty screen. FUN FUN FUN...

FINAL SOLUTION (that worked for me).

  1. Define a derective:

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. Add it as a directive to anywhere that uses it:

directives: [TrackScrollDirective]

  1. Add the attribute to any element where we want to track the event:

<div class="col-md-12" track-scroll>

解决方案

I think the easiest way is each interested component listening to the scroll event.

  @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 using @HostListener()

Hint:

bootstrap(MyComponent, [
    provide(PLATFORM_DIRECTIVES, {useValue: [TrackScrollDirective], multi:true})]);

makes the directive universally without adding it to every components directive: [...] list.

这篇关于跟踪滚动位置并通知其他组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆