简体   繁体   English

Angular - 对象的值更改未通过更改检测注册

[英]Angular - Value change of object not registering through change detection

i'm relatively new to learning Angular and have followed some instructions from a PluralSight demo on setting up a basic service, component and HTML page.我对学习 Angular 还比较陌生,并遵循了 PluralSight 演示中关于设置基本服务、组件和 HTML 页面的一些说明。

When I run my service and debug, I can see that the service is successful in retrieving the data I need.当我运行我的服务并进行调试时,我可以看到该服务已成功检索到我需要的数据。 However, part of the HTML doesn't seem to go through change detection.但是,部分 HTML 似乎没有经过更改检测。 The date attribute I display does this successfully, however my array just gets ignored.我显示的日期属性成功地做到了这一点,但是我的数组只是被忽略了。

I've tried explicitly creating a separate array and assigning to a different variable, which also didn't work.我试过显式创建一个单独的数组并分配给不同的变量,这也不起作用。 Is there something around the ngModel and change detection I am missing?我缺少 ngModel 和更改检测周围的东西吗?

Service:服务:

@Injectable({
  providedIn: 'root'
})
export class RankingService {
  private rankingUrl = 'https://localhost:44381/api/Ranking'

  constructor(private http: HttpClient) { }

  getRanking(): Observable<IRanking> {
    return this.http.get<IRanking>(this.rankingUrl)
      .pipe(
        tap(data => console.log('All: ' + JSON.stringify(data))),
        catchError(this.handleError)
      );
  }

HTML: HTML:

<div class='row'>
  {{'Last Updated: ' + ranking?.startDateTime}}
</div>
<table class='table' *ngIf='ranking'>
  <thead>
    <tr>
      <th>Rank</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor='let position of ranking.rankpositions?.slice(0,30)'>
      <td>
        {{ position.Rank }}
      </td>
    </tr>
  </tbody>
</table>

Component:成分:

export class RankingListComponent implements OnInit {
  errorMessage = '';
  ranking: IRanking;

  constructor(private rankingService: RankingService) { }

  ngOnInit(): void {
    this.rankingService.getRanking().subscribe({
      next: ranking => {
        this.ranking = ranking;
      },
      error: err => this.errorMessage = err
    });
  }

}

IRanking is an interface, with an array of rankPositions (Which represents another Interface). IRanking 是一个接口,带有一个 rankPositions 数组(代表另一个接口)。

As an output I get this (I've removed some HTML elements, to make the code segment smaller):作为输出,我得到了这个(我删除了一些 HTML 元素,使代码段更小):

在此处输入图片说明

In the console, I clearly have the rankpositions array populated:在控制台中,我清楚地填充了 rankpositions 数组: 在此处输入图片说明

you've got a typo, so this should be closed.你有一个错字,所以这应该关闭。

but beyond that, running functions like that in template is pretty much always going to cause you change detection problems.但除此之外,在模板中运行类似的功能几乎总是会导致您更改检测问题。 use the slice pipe instead here for a quick fix:在这里使用slice管道进行快速修复:

<tr *ngFor='let position of ranking.rankPositions | slice:0:30'>

a better fix IMO would be switching to async pipe and using rx operators to run your slice.更好的修复 IMO 将切换到async管道并使用 rx 运算符来运行您的切片。

a general angular best practice is to not run functions in templates, use pipes when appropriate, but generally your functions should be running in your component controller.一般的角度最佳实践是不在模板中运行函数,在适当的时候使用管道,但通常你的函数应该在你的组件控制器中运行。

请将rankpositions更改为rankPositions

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM