Angular @Input() 不更新子级中的 UI

oss*_*sys 5 html javascript typescript angular

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

子代码看起来像这样:

子组件.ts

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

子组件.html

<table>
  <tr *ngFor="let item of data"><td>{{ item }}</td></tr>
</table>
Run Code Online (Sandbox Code Playgroud)

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

父组件.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;
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

父组件.html

<child [data]="data"></child>
Run Code Online (Sandbox Code Playgroud)

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

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

所以看起来我可以通过在父组件中运行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();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

Mis*_*sov 9

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

this.endpointService.loadData().subscribe((response) => {
  this.data = [...response];
});
Run Code Online (Sandbox Code Playgroud)