首页 > 解决方案 > Angular @Input() 不更新子用户界面

问题描述

我已经实现了一个子组件来根据通过@Input() 提供的列表来呈现表格。数据是通过 http 加载的,但是 UI(子组件)不会更新,除非我在屏幕上挥动鼠标。我已经看到人们发布了关于在我的孩子中实现 ngOnChanges() 的帖子,但我认为 Angular 应该默认执行此操作?我错过了什么吗?为什么 UI 不会随之更新?

子代码如下所示:

child.component.ts

@Component({
  selector: 'child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.scss'],
})
export class ChildComponent implements {
  @Input() data: any[] = [];
  constructor() {}
}

child.component.html

<table>
  <tr *ngFor="let item of data"><td>{{ item }}</td></tr>
</table>

使用该组件的父代码如下所示:

父组件.ts

@Component({
  selector: 'parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss'],
})
export class ParentComponent implements OnInit {
  data: string[] = [];

  constructor(private endpointService: EndpointService) {}

  ngOnInit() {
    // response is a string array like: ['hello', 'world']
    this.endpointService.loadData().subscribe((response) => {
      this.data = response;
    });
  }
}

父组件.html

<child [data]="data"></child>

============================== 编辑==================== ===============

我验证了它仅在订阅回调内部更新时加载失败(如果我设置了一个静态数组,它加载就好了)。

所以看起来我可以通过在父组件中运行 changeDetectorRef.detectChanges() 来解决这个问题,但这感觉就像我不应该这样做一样。这是解决这个问题的好方法吗?或者这是否表明我的实现有问题?

父组件.ts

@Component({
  selector: 'parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.scss'],
})
export class ParentComponent implements OnInit {
  data: string[] = [];

  constructor(private endpointService: EndpointService,
              private changeDetectorRef: ChangeDetectorRef) {}

  ngOnInit() {
    // response is a string array like: ['hello', 'world']
    this.endpointService.loadData().subscribe((response) => {
      this.data = response;
      this.changeDetectorRef.detectChanges();
    });
  }
}

标签: javascripthtmlangulartypescript

解决方案


您还可以尝试通过例如扩展运算符强制值引用更新来强制更改检测:

this.endpointService.loadData().subscribe((response) => {
  this.data = [...response];
});

推荐阅读