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

时间:2018-06-01 07:16:29

标签: angular 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中的单个项目)。

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

期望的结果

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

通过Google搜索,我似乎明白,通过查看用于生成ngFor项目的对象引用,Angular 仅检测到DOM的更改,这样如果我只更改了Object / Item的一些内部属性,没有触发ChangeEvent。

Possibile解决方案

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

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

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

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

提前谢谢大家

修改

确定。可能上面发布的代码有点过于简单了。

这里的这个更接近我的真实世界应用程序,并且正在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 :(得分:0)

根据您的要求,如果您不想更新整个组[]但只想更改DOM中的特定组标题,您可以做的一件事就是将组的索引传递给单击事件并使用它来动态生成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>

在这里你可以利用那个索引&#34; i&#34;要更新您的论坛[],然后由于您可以使用唯一ID进行访问,您可以更改其中的值。

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

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