获取 cdk-virtual-scroller 中的静态组件引用? (参考文献已回收)

2023-11-25

我们最近将可滚动列表转换为 CDK Virtual Scroller。 (Angular 7.2.12 和 Angular/cdk 7.3.7)

简而言之,似乎VirtualScrollViewport正在回收组件实例,而不仅仅是文档建议的模板。

StackBlitz 上的实时 MCVE(更新以反映编辑 1)。

EDIT 1

一位同事提醒我,我们现在使用命名引用而不是ViewChildren(),像这样:

HelloComponent(在 - 的里面*cdkVirtualFor):

@Component({
  selector: 'hello',
  template: `<h1 [class.active]="active">Data Item {{item}} !</h1>`,
  styles: [`.active {background-color: red; color: white}`]
})
export class HelloComponent  {
  @Input() item: any;
  active: boolean = false;
  toggle = () => this.active = !this.active;
}

并在应用程序中实现它,例如:

<cdk-virtual-scroll-viewport itemSize="75">
  <ng-container *cdkVirtualFor="let item of data" templateCacheSize=0>
    <hello #hi [item]="item" (click)="clickByReference(hi)"></hello>
  </ng-container>
</cdk-virtual-scroll-viewport>

// Non-essentials hidden, see StackBlitz
export class AppComponent  {
  data = Array.from(Array(100).keys())
  clickByReference = (element: any): void => element.toggle();
}

它将把单击的元素的背景颜色更改为红色,但是当滚动时,其他元素(大概是那些与某些缓存索引匹配的元素?)已经是红色了!激活其中之一也会清除原始内容。

消息来源暗示 that templateCacheSize可能有帮助,但没有帮助。

Original

可滚动区域包含我们通过@ViewChildren() and QueryList我们使用索引来跟踪我们正在对哪一个进行操作*ngFor (now *cdkVirtualFor),像这样:

<cdk-virtual-scroll-viewport itemSize="75">
  <ng-container *cdkVirtualFor="let item of data; let i = index">
    <hello  #hi
            [item]="item"
            (click)="click(i)"></hello>
  </ng-container>
</cdk-virtual-scroll-viewport>

然后,从页面中,我们与列表中的组件进行通信:

export class AppComponent  {
  @ViewChildren('hi') hiRefs: QueryList<HelloComponent>;
  data = Array.from(Array(100).keys())

  click = (i: number) => this.hiRefs["_results"][i].say(`Hello as ${i}`);
}

当然,现在模板是在虚拟滚动容器中渲染的,只有第一个n被渲染到 DOM 中。因此,如果您向下滚动列表超出最初加载的内容,hiRefs不包含对具有相应索引的项目的引用,抛出ReferenceError对于提供的["_results"][i].

我尝试过trackBy但没有取得任何成果。

EDIT:一位同事也尝试传递一个命名引用,奇怪的是它也有同样的问题。

更新中HelloComponent to

@Component({
  selector: 'hello',
  template: `<h1 [class.active]="active">Data Item {{item}} !</h1>`,
  styles: [`.active {background-color: red}`]
})
export class HelloComponent  {
  @Input() item: any;
  active: boolean;

  say = (something: any) => this.active = !this.active;
}

并在应用程序中实现它,例如:

<hello #hi [item]="item" (click)="clickByReference(hi)"></hello>

它将把单击的元素的背景颜色更改为红色,但是当滚动时,其他元素(大概是那些匹配相同索引的元素)将已经是红色的,尽管没有使用 @ViewChildren() QueryList at all!

看来CDK正在回收组件实例引用?

我用该方法更新了 StackBlitzclickByReference(),并将上面的重命名为clickByIndex().

如何正确获取列表中组件的引用以便调用其方法?


默认情况下,CdkVirtualForOf 缓存 20ViewRefs不再渲染到 DOM 中的组件以提高滚动性能。

虽然这些会更新以显示新的绑定@Input()s,它们不会更新其内部状态,因此先前缓存的副本将被重新使用。

看来唯一的解决办法是设置templateCacheSize: 0:

<ng-container *cdkVirtualFor="let item of data; templateCacheSize: 0">

这样,一旦组件不再可见,它们就会被销毁,状态也会丢失。

进一步阅读https://github.com/angular/material2/issues/15838 and a doc PR.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取 cdk-virtual-scroller 中的静态组件引用? (参考文献已回收) 的相关文章

随机推荐

  • 将 C++ 中的字符串转换为大写

    如何将字符串转换为大写 我从谷歌搜索中找到的例子只需要处理字符 include
  • 如何使用字典执行多个搜索和替换操作? [复制]

    这个问题在这里已经有答案了 我必须在地址字段中将 北 南 等文本替换为 N S 等 我想到制作一本字典来保存替换内容 假设我们有 replacements NORTH N SOUTH S EAST E WEST W address 123
  • 如何在 JSP 中从 /main/resources 链接 Web 资源文件?

    我的 java webapp 中有以下结构 main java resources lib css style css webapp WEB INF web xml index jsp 如何将 style css 链接到我的索引 jsp 这
  • AngularFire - 如何查询非规范化数据?

    好的 我刚刚开始使用 Firebase 我读过这个 https www firebase com docs data struct html我读过这个 https www firebase com blog 2013 04 12 denor
  • C++ 结构体的 stlpriority_queue

    我们如何使用STLpriority queue对于结构 任何插图推入和弹出的过程中 结构体有多种数据类型 Say struct thing int a char b glass 10 现在我如何使用 int a 将这个结构放在priorit
  • Thread.CurrentThread.Join() 什么时候有意义?

    调用 Thread CurrentThread Join 的效果是什么 是否 何时调用它才有意义 真的是吗 CurrentThread Join 你在真实代码中看到的 我有点怀疑 除非这是一些阻止其他线程加入当前线程的黑客 或者是 Curr
  • spring-cloud-starter-openfeign:无效的 HTTP 方法:PATCH 执行 PATCH

    Context 我有一个 Spring Boot 版本 2 2 6 RELEASE Web 项目 从这个 Web 应用程序 我称之为 APP1 中 我想使用另一个 Web 应用程序 我们称之为 APP2 的 PATCH 方法调用另一个 UR
  • NSCollectionView 与部分 - 就像在 iPhoto 中一样

    我想构建一个类似于 iPhoto 11 中的 NSCollectionView 我想将几张图片分组到部分中 并创建一个部分标题 特定节的节标题始终可见 直到该节的最后一个元素可见 你可以看看图片就明白我的意思了 编辑 我应该补充一点 内容不
  • C# 中的延迟函数

    我需要了解如何在一组命令之间创建延迟 我的背景是 C DOS 现在在 Visual Studio 2015 中使用 C 重温这些概念 这是我正在努力解决的代码 using System Threading private void butt
  • 如何在 Cloud Api Gateway 的响应正文中添加一些数据

    我正在将一些身份验证逻辑添加到云 api 网关中 我添加了网关过滤器 import java util List import org springframework cloud gateway filter GatewayFilter i
  • 我想在我的手机上安装未签名的 apk 文件。该怎么办? [关闭]

    Closed 这个问题是无关 目前不接受答案 我已经构建了一个应用程序 我通过Eclipse APK导出它 我有 APK 文件 我想将其发送给我的父亲 在另一个国家 因此无法做很多技术工作 以便他可以安装它并查看我的进度 如果没有在 Pla
  • 使用 AVFoundation 切换摄像头时视频冻结

    我制作了一个具有捕获和保存视频功能的应用程序 我为此使用了 AVFoundation苹果的AVCam一直是我的向导 我希望我能说清楚 一切工作正常 直到我第一次释放处理 AVCamCaptureManager 的 videoViewCont
  • 为什么 if 语句中的表达式顺序很重要

    假设我有一个IF健康 状况 if A B left do something 现在假设A那么更有可能获得真实值B 为什么我要关心左边哪一个 如果我把它们都放在IF括号 那么我就知道 作为代码的程序员 双方都是需要的 问题是 我的教授在他的讲
  • Laravel Eloquent 嵌套查询

    我正在使用 Laravel 并陷入了困境 我有以下型号 类别 Product 类别产品 CategoryProduct保存有关哪个产品属于哪个类别的信息 一个产品可能属于多个类别 现在 当我想加载属于特定类别的所有产品时 我需要运行查询Pr
  • 根据浏览器包含不同的 JavaScript 文件?

    我只想在浏览器不是 IE 时才包含 JavaScript 文件 有什么办法可以做到这一点吗 2022 年更新 为您提供一些选择 让您的服务器查看User Agent标头并向 Internet Explorer 发送与其他浏览器不同的 HTM
  • Android 中使用 java 的方法 Swizzling

    是否可以使用java在android中进行方法调配 我想拦截一个系统方法并记录其参数 然后正常处理它 我认为该技术不能在任何环境中使用 Java 来使用 也许您可以使用 AOP 获得类似的结果 但在 Android 上你能用它做的事情看起来
  • 对未命名临时对象的引用(生命周期)

    看完之后这个答案 from ildjarn 我写了下面的例子 看起来一个未命名的临时对象和它的引用有相同的生命周期 这怎么可能 C 标准中有规定吗 哪个版本 源代码 include
  • 从网络位数转换为网络掩码的最佳方法是什么?

    例如 如果我有一个像 172 20 10 0 24 这样的网络规范 24 就是位数 将其转换为像 0xffffff00 这样的网络掩码的最佳方法是什么 假设 32 位掩码和 32 位 int int keepBits 24 actually
  • 将多个模型的回归系数打印到共享数据框

    我知道这有点初级 基本上 我想将 coef 函数中的保存数据用于模型的共享数据框架 这些模型都从更大的共享数据集中提取有限的可能变量 我有3套14个模型 每组使用 100 个变量数据集中的 15 25 个变量 每个模型混合使用约 12 个变
  • 获取 cdk-virtual-scroller 中的静态组件引用? (参考文献已回收)

    我们最近将可滚动列表转换为 CDK Virtual Scroller Angular 7 2 12 和 Angular cdk 7 3 7 简而言之 似乎VirtualScrollViewport正在回收组件实例 而不仅仅是文档建议的模板