angular - Angular - 如何 MarkForCheck() ngfor 模板中的单个项目
问题描述
我对 Angular 比较陌生,所以请原谅我可能是微不足道的问题。
我也搜索了很多,发现了很多类似的问题,但没有一个真正解决我的问题。
情况
让我们假设以下组件的模板:
<div class="wrapper">
<!-- Stuff -->
.
.
.
<div *ngFor="let group of groups">
<button #btn (click)="onClick(btn, group)">Change group title</button>
<div class="group-title">
{{group.title | translate}}
</div>
.
.
.
<div *ngFor="let item of group.subGroup">
{{item.title}}
.
.
.
</div>
</div>
<div/>
现在我希望用户能够触发一系列最终更改单个组(ngFor 中的单个项目)标题的操作/事件。
IE
onClick(btnRef, group) {
.
.
.
anAsyncronousEvent.subscribe(
success => group.title = success.BrandNewTitle;
)
}
期望的结果
DOM 应该显示受影响组的新标题,但它没有。我也尝试过不使用“翻译”管道,但徒劳无功。
通过谷歌搜索,我似乎明白只有通过查看用于生成 ngFor 项目的对象引用,Angular 才能检测到 DOM 的变化,因此如果我只更改对象/项目的某些内部属性,则不会触发 ChangeEvent .
可能的解决方案
一个想法可能是制作组对象的深层副本并替换 ngFor 后面数组中的相应项目,但这会削弱使 Angular仅针对真正更改的内容刷新 DOM 的整个混乱。另一个想法可能是使用 markForCheck() 但在这里我有两个选择:
1) 在 clickHandler 中使用 markForCheck() ,但同样,这会触发组件中所有组的重新渲染。
2)我可以以某种方式仅为组标题创建一个子组件,但在我看来这有点矫枉过正,我也不确定它是否会起作用。
那么,如何强制 Angular 仅刷新组标题?
谢谢大家
编辑
好的。可能上面发布的代码有点过于简单了。
这里的这个更接近我的真实世界应用程序,并且在这里的 stackblitz 上运行,它重现了我试图解决的问题。
// Template
<div class="wrapper">
<div *ngFor="let group of groups">
<button #btn (click)="onClick(btn, group)">Pop away item</button>
<div class="group-title">
Group info: count = {{group.info | format}}
</div>
<div *ngFor="let item of group.items">
Item title: "{{item.title}}"
</div>
</div>
</div>
//Component
onClick(btn, group: any) {
setTimeout(() => { // In the real App this is an Observable
let i = this.groups.indexOf(group);
group.items.pop();
group.info.count--;
}, 1000);
}
我希望单击按钮后显示的项目数会减少,但事实并非如此。
解决方案
根据您的要求,如果您不想更新整个组 [] 但只想更改 DOM 中的特定组标题,您可以做的一件事是将组的索引传递给 click 事件并使用它动态生成 id,以便您可以在触发事件时访问该 id 并更改 HTML 值。像下面的东西
<div *ngFor="let group of groups; let i = index">
<button #btn (click)="onClick(btn, group, i)">Change group title</button>
<div class="group-title" id="group{{i}}">
{{group.title | translate}}
</div>
.
.
.
<div *ngFor="let item of group.subGroup">
{{item.title}}
.
.
.
</div>
</div>
在这里,您可以使用该索引“i”来更新您的 groups[],然后由于您可以使用唯一 id 访问,您可以更改该 .
onClick(btnRef, group, index) {
.
.
.
anAsyncronousEvent.subscribe(
success => {
document.getElementById(`group${index}`)
.text(success.BrandNewTitle);
}
)
}
或者,您可以使用可以传递每个组数据的组件,在这种情况下,您可以仅显式重新加载该组组件
推荐阅读
- pgadmin-4 - Can you run pgAdmin 4 v3 as desktop app?
- twitter - Twitter Oauth:如何通过验证和获取用户详细信息
- css - Column-count > 1 增加父 inline-block 元素的高度
- javascript - Laravel 5.6 Auth::check() 如果使用 fetch 调用返回 false
- node.js - NodeJS Express 在进行 POST 时获取 URL 参数
- jquery - 将鼠标悬停在列表项上时,使 div 在一段时间内可见
- javascript - 仅预加载文本/小数百分比百分比计数器
- pycharm - 在同一视图中打印具有 11 列的数据框的输出 - Pycharm
- java - Android学校项目-错误调用摄像头服务
- r - 使用 json 文件根据 R 中的变量删除某些数据行