为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕容森 2023-10-20 10:23:13
我已经实现了一个子组件来根据通过 @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() {}}子组件.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();    });  }}
查看完整描述

4 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

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

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


查看完整回答
反对 回复 2023-10-20
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

我已经解决了这个问题,更新了子输入传递的属性,而不是重新分配它。我认为 Angular 将输入作为副本传递。所以,在订阅正文中你应该使用

resultOfSubscribe.forEach((v) => varPassedByInput.push(v));



查看完整回答
反对 回复 2023-10-20
?
隔江千里

TA贡献1906条经验 获得超10个赞

我用静态字符串数组替换了该服务,效果很好。我认为可观察订阅有问题。


子组件.ts


import { Component, OnInit,Input } from '@angular/core';


@Component({

  selector: 'child',

  templateUrl: './child.component.html',

  styleUrls: ['./child.component.css']

})

export class ChildComponent implements OnInit {

@Input() data: any[] = [];

  constructor() { }


  ngOnInit() {

  }


}

父组件.ts


import { Component, OnInit } from '@angular/core';


@Component({

  selector: 'parent',

  templateUrl: './parent.component.html',

  styleUrls: ['./parent.component.css'],

})

export class ParentComponent implements OnInit {

  data: string[] = [];


  constructor() {}


  ngOnInit() {

    

      this.data = ['hello', 'world','aaa','ddd'];

    

  }

}


查看完整回答
反对 回复 2023-10-20
?
波斯汪

TA贡献1811条经验 获得超4个赞

模板表达式中似乎存在一些其他错误,导致整个模板失败。这是我创建的 stackblitz,一切正常:https://stackblitz.com/edit/angular-ivy-w2ptbb ?file=src%2Fapp%2Fhello.component.ts

您在控制台中可能有一些错误吗?


查看完整回答
反对 回复 2023-10-20
  • 4 回答
  • 0 关注
  • 137 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信