当前位置: 首页 > 知识库问答 >
问题:

Angular ngOnChanges不更新视图

胡昊
2023-03-14

tl;dr:ngOnChanges显示在输入属性上检测到更改,但视图未更新

我正在开发一个Angular(2+)应用程序,试图为一个异步任务创建一个进度条,该任务由一个服务使用可观察的。Observable将数字作为数据推送,以指示任务已完成的百分比。涉及三个部分:服务、ResultsComponent和ProgressBarComponent(ResultsComponent的子级)。基本数据流是:

  1. 从Observable推送到ResultsComponent的数
  2. ResultsComponent.PercentLoaded设置为等于此数
  3. ProgressBarComponent使用percentLoaded作为输入并更新视图

问题是视图实际上没有被更新。

在ResultsComponent中,我有以下块:

this.service.doTheTask()
    .subscribe(
      data => {
        this.percentLoaded = data;
        this.ref.detectChanges();
      },
      e => console.log('error:', e),
      () =>  {
        this.isLoading = false;
        this.percentLoaded = 0;
      }
    );

添加ref.detectChanges()成功地使ProgressBarComponent中的OnChanges钩子触发。组件和模板如下所示:

组件

export class ProgressBarComponent implements OnChanges {
  @Input() percentLoaded = 0;

  constructor() { }

  ngOnChanges(changes) {
    console.log('changes: ', changes);
  }
}

模板

<div class="meter">
  <div class="percent" [style.width.%]="percentLoaded"></div>
</div>
<p>{{percentLoaded}}% Loaded</p>

正如您所看到的,我只是记录更改以进行测试。我已经验证了ngOnChanges正在启动,并且值是正确的。我读到的所有内容都说“一旦检测到更改,视图就会自动更新”,所以我不知道还能做什么。

有什么建议吗?

共有1个答案

公西天逸
2023-03-14

异步任务完成后,使用以下行this.percentLoade=0;覆盖从订阅接收的数据。删除它:

() =>  {
   this.isLoading = false;
   //delete this line this.percentLoaded = 0;
}

此外,您的更改检测也不会被触发,因为只有当对象的引用被更改时,输入上的更改检测才会被触发。Number是一个简单的变量,而不是引用变量,因此在您的情况下,不会触发更改检测。我的建议是在两个组件中订阅服务,并且只从子组件触发更改检测。

export class ProgressBarComponent {
  percentLoaded: number = 0;

  constructor(private ref: ChangeDetectorRef, private service: TheService) { }

  this.service.doTheTask()
   .subscribe(
     data => {
     this.percentLoaded = data;
     this.ref.detectChanges();
   },
}
 类似资料:
  • 问题内容: 我目前正在使用基于Web的Twitter客户端,因此我使用了angular.js,node.js和socket.io。我通过socket.io将新的推文推到我的客户端,服务在其中等待新的推文。当一条新的推文到来时,该服务通过$ broadcast发送事件。 在我的控制器中是一个事件侦听器,其中传入的tweet在单独的函数中进行处理。此功能只是将新的推文推入我的推文范围。 现在,我的问题

  • 问题内容: 我已经阅读了有关此问题的主题,例如:[\AngularJS中未更新视图,\但我仍然不明白如何在我的简单示例中应用它。 我有这个功能: 当代码中的其他地方更新时(用户单击,交互,发送XHR请求时),它不会更新我的视图。我知道我需要使用$apply做些事情,但我不知道在哪里以及如何做。 有人可以向我解释如何针对这个简单用例解决此问题吗? 我的模型看起来像这样(如果这个问题是必要的)-它里面

  • 问题内容: 添加评论时,我试图使angular.js视图本身进行更新。我的代码如下: 范围在输入时更新: 调试$ scope.currentItem显示注释已添加到其中,但是视图未显示新注释。我怀疑$ scope仅在其第一级被监视,这就是为什么视图不更新的原因。是这样吗?如果可以,我该如何解决? 解决方案:正如Ajay在下面的回答中所建议的那样,我将数组推入包装为apply函数,如下所示: 问题答

  • 问题内容: 我目前正在尝试弄清楚如何在不重新加载整个页面的情况下更改路由参数。例如,如果我从 http://www.example.com/#/page 但将名称更新为“乔治”,将路线更改为: http://www.example.com/#/page/george 如果我已经路由了http://www.example.com/#/page/:name。 无需重新加载位置。可以只设置$ route

  • 我有一个聊天应用程序,可以打开一个到服务器的Websocket。该应用程序有2个模块- chat sdk:处理连接和来回消息传递。 用户界面:处理适配器和视图 聊天UI位于活动托管的片段上。 一切都很好,但当我决定在设备旋转上使用持久性时,我遇到了问题。当我旋转设备时,websocket重新连接(这是正常的),活动被重新创建,片段也被重新创建。 经过设备旋转和一些调试,我看到我的消息列表被正确填充

  • 我想在android中从mysql数据库中检索数据,并在textview中显示 这是后台asynctask代码 }