首页 文章

Angular - 如何在ngfor模板中使用MarkForCheck()单项

提问于
浏览
0

我对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/>

现在我希望用户能够触发一系列最终改变单个组 Headers 的动作/事件(ngFor中的单个项目) .

onClick(btnRef, group) {
    .    
    .    
    .
    anAsyncronousEvent.subscribe(
        success => group.title = success.BrandNewTitle;
    )    
}

期望的结果

DOM应显示受影响组的新 Headers ,但不会 . 我也试过没有'翻译'管道,但是徒劳无功 .

通过Google搜索,我似乎明白Angular仅通过查看用于生成ngFor项的 object reference 来检测DOM的更改,因此如果我只更改了Object / Item的某些内部属性,则不会触发ChangeEvent .

Possibile解决方案

一个想法可能是制作组对象的深层副本并替换ngFor后面的数组中的相应项目,但这将削弱使Angular刷新DOM仅用于真正改变的整个混乱 . 另一个想法可能是使用markForCheck(),但在这里我有两个选择:

1)在clickHandler中使用markForCheck(),但同样,这将触发组件中所有组的重新呈现 .

2)我可以以某种方式为组 Headers 创建一个子组件,但在我看来有点矫枉过正,我也不确定它会起作用 .

那么,我如何强制Angular只刷新组 Headers ?

谢谢大家

编辑

好 . 上面发布的代码可能有点过于简单了 .

这里的这个更靠近我的真实世界应用程序,并在stackblitz here上运行,它重现了我正在尝试解决的问题 .

// 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">
            &nbsp;&nbsp;&nbsp;&nbsp;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);
}

我希望按钮点击后项目数量会减少,但事实并非如此 .

1 回答

  • 0

    根据您的要求,如果您不想更新整个组[]但只想更改DOM中的特定组 Headers ,您可以做的一件事就是将组的索引传递给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”更新您的组[],然后由于您可以访问唯一ID,您可以更改其中的值 .

    onClick(btnRef, group, index) {
    .    
    .    
    .
    anAsyncronousEvent.subscribe(
        success => {
             document.getElementById(`group${index}`)
                 .text(success.BrandNewTitle);
          }
        )    
      }
    

    或者,您可以使用可以传递每个组数据的组件,在这种情况下,您可以显式地仅重新加载该组组件

相关问题