Angular 6滚动监听器重新加载组件

7
为了尽可能简单地阐述,这是我的情况:
1)我有一个父组件,它有一个ViewContainerRef来动态加载父组件中的组件。对于我的用例,父组件是一个空的容器页面,根据一组变量动态替换自身为另一个页面。 2)子组件有一个水平滚动的div,类似于以下内容: 每当带有(scroll)监听器的div被滚动时,它都会重新加载父组件,因此滚动位置总是反弹回0,因为它已经重新加载了。
然而,如果我删除(scroll)监听器,则div可以正常滚动。问题是,我想根据水平滚动位置动态更改页面上的项目。
是否有人对嵌入式组件和滚动监听器可能出现的问题有什么想法?非常感谢!

onScroll() 函数是做什么用的? - GreyBeardedGeek
现在它所做的只是console.log事件,什么都没有。即使函数中没有任何内容,它也会以这种方式运行。@GreyBeardedGeek - Brayden
(scroll)事件处理程序的存在会在每次滚动div时触发变更检测。我们应该查看其余的标记和代码,以确定变更检测是否导致组件重新加载。 - ConnorsFan
为了测试我之前评论的假设:(1)删除(scroll)事件处理程序,(2)在构造函数或ngOnInit中调用setInterval(() => { this.applicationRef.tick(); }, 5000),每5秒强制进行一次变更检测,(3)滚动div并检查当变更检测发生时组件是否重新加载。 - ConnorsFan
你尝试过使用renderer和viewchild来订阅onscroll事件吗? - karoluS
显示剩余3条评论
4个回答

3
我怀疑 onScroll 触发了 Angular 的变更检测器(正如评论所建议的那样),出于某种原因,变更检测器决定页面已经被修改 -- 这将触发页面重绘。如果是这种情况,我怀疑重绘会重置轮播图 div。
为了确认这一怀疑,您可以在有问题的组件上更改 ChangeDetectionStrategyChangeDetectionStrategy.OnPush 只有在绑定到 @Input()(例如下面的 data)的数据发生更改或者您明确告诉它要这样做时才重新绘制组件。
@Component({
  selector: 'app-neat',
  templateUrl: './neat.component.html',
  // Add this line to your component
  changeDetection: ChangeDetectionStrategy.OnPush 
})
export class NeatComponent {
  @Input() data: string[];
}

这意味着当你想要组件重新绘制时,你需要显式地告诉Angular去做。你可以这样做:
@Component({
  selector: 'app-neat',
  templateUrl: './neat.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent {
  @Input() data: string[];

  // Inject the ChangeDetectorRef into your component
  constructor(private cd: ChangeDetectorRef) {}

  refresh() {
    // Manually tell Angular to detect changes and redraw the screen
    this.cd.detectChanges();
  }
}

你可以在这里找到更多信息:https://alligator.io/angular/change-detection-strategy/ 当滚动事件被触发时,这将允许你对页面上的内容进行细粒度控制,以便重新绘制。
如果你发布更多代码,我们可能能够提供更具体的答案。

哦,经过数小时的搜索,这就是解决我的问题的方法...谢谢!!! - romeouald

2

我不知道您是否像这样注入组件,但这是我的尝试来解决这个问题。

我使用了渲染器来监听子组件中的窗口滚动事件。

StackBlitz

不要在意我的样式


0

如果您直接从子组件使用 window 对象,它将始终返回零

由于您想从子组件使用 window 滚动事件,因此可以使用事件对象来获取 ScrollY 值

Child.html

 <p (window:scroll)="onScroll($event)" >
    demo Scroll Value{{scrollValue}}
    </p>

child.component.ts

 onScroll($e){
    this.scrollValue=$e.path[1].scrollY;
    console.log($e.path[1].scrollY);
  }

Example:https://stackblitz.com/edit/viewcontainer


0
  import { HostListener } from '@angular/core';

  @HostListener("window:scroll", ["$event"])
  onWindowScroll() {
    let scrollTop = (document.documentElement.scrollTop || document.body.scrollTop);
    let clientHeight =  document.documentElement.clientHeight;
    let scrollHeight = document.documentElement.scrollHeight;
    if ((scrollTop + clientHeight) >= scrollHeight) {
       //FUNCTIONS WHEN BOTTOM
    }
    else if ((scrollTop + scrollHeight) == scrollHeight) {
       //FUNCTIONS WHEN TOP
    }
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接