我正在使用angular 17,我从我的API中获取数据,但在收到它之后,模板不更新,我无法显示我的数据.

我的组件服务,我向服务器发送请求:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable, tap } from 'rxjs';
import { APIBASEURL } from 'app/constants.config';


@Injectable({
  providedIn: 'root'
})
export class DashboardService {

  constructor(
    private http: HttpClient
  ) { }

  getData(): Observable<any> {
    return this.http.get(`${APIBASEURL}/dashboard/links`)
  }


}

我的组件,其中我订阅了前面的方法:

import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { FuseCardComponent } from '@fuse/components/card';
import { DashboardService } from './dashboard.service';
import { Subject, takeUntil } from 'rxjs';
import { MatIconModule, MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
// import { CustomIconDirective } from './custom-icon.directive';
import {MatInputModule} from '@angular/material/input'; 
import {MatSlideToggleModule} from '@angular/material/slide-toggle';
import {MatButtonModule} from '@angular/material/button';
import { UserService } from 'app/core/user/user.service';
import { User } from 'app/core/user/user.types';


@Component({
  selector: 'app-dashboard',
  standalone: true,
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush,
  imports: [CommonModule, FuseCardComponent, MatIconModule, MatInputModule, MatSlideToggleModule, MatButtonModule],
  templateUrl: './dashboard.component.html',
})


export class DashboardComponent implements OnInit, OnDestroy {

  data: any;

  private unsubscribeAll: Subject<any> = new Subject<any>();


  constructor(
    private dashboardService: DashboardService,
    private matIconRegistry: MatIconRegistry,
    private domSanitizer: DomSanitizer,
    private _userService: UserService,

  ) { }

  ngOnInit() {

    // Subscribe to the dashboard service
    this.dashboardService.getData().subscribe((data) => {
      this.data = data;
      console.log('subscribe: ', this.data);
    });

    console.log('after: ', this.data)
  }

  ngOnDestroy(): void {
    this.unsubscribeAll.next(null);
    this.unsubscribeAll.complete();
  }

}


之后,在模板中我只是显示我的数据,但它总是空的.

如果我查看控制台中的devtool,我会发现,首先第二个控制台日志(log)显示的是第一个,然后是第二个,数据正确.

经过大量研究,我发现如果我这样做: this.data = this.dashboardService.getData()个 而不是订阅,然后在模板中放置异步 @if(data | async; as data)这行得通,但我想知道为什么订阅行不通.

让你知道我是新的Angular ,这是我的第一个网站.

如我所说,我试过使用第二种方法,但我想知道为什么第一种方法行不通

推荐答案

OnPush更改检测将仅在@input值更改或模板中的可观察边界发出时更新视图.

要解决这个问题,你可以按照@ Jacopo Sciampi的建议手动调用detectChanges.

或者,您可以使用默认更改检测.

或者,你可以保持你的数据是可观察的,并使用pilc管道,这是我发现通常最简单的代码:

export class DashboardComponent {

  data$: Observable<any> = this.dashboardService.getData();

  constructor(
    private dashboardService: DashboardService,
    private matIconRegistry: MatIconRegistry,
    private domSanitizer: DomSanitizer,
    private _userService: UserService,
  ) { }

}
<ng-container *ngIf="data$ | async as data">

  <p> My data </p>
  <pre>{{ data | json }}</pre>

</ng-container>

请注意,如果模板中没有显式订阅,则不再需要管理取消订阅,因此不再需要SubjectngOnDestroy.如果你在声明data$时初始化它,你也不需要ngOnInit.


此外,如果您确实决定需要一些显式订阅(usually in components this is not necessary),则可以利用新的takeUntilDestroyed()操作符:

private sub = this.dashboardService.getData().pipe(takeUntilDestroyed()).subscribe(
   data => this.data = data
);

Javascript相关问答推荐

获取POS餐厅会话用户/收银员

Vue v模型检测父参考更改

React对话框模式在用户单击预期按钮之前出现

主要内部的ExtJS多个子应用程序

Redux工具包查询(RTKQ)端点无效并重新验证多次触发

被CSS优先级所迷惑

拖放仅通过 Select 上传

togglePopover()不打开但不关闭原生HTML popover'

使用i18next在React中不重新加载翻译动态数据的问题

查找最长的子序列-无法重置数组

当Redux提供程序访问Reduxstore 时,可以安全地从Redux提供程序外部调用钩子?

用于编辑CSS样式的Java脚本

在Java中寻找三次Bezier曲线上的点及其Angular

如何将zoom 变换应用到我的d3力有向图?

MongoDB受困于太多的数据

在表单集中保存更改时删除';禁用';

Phaser3 preFX addGlow不支持zoom

如何使用画布在另一个内部绘制一个较小但相同的形状,同时保持恒定的边界厚度?

输入的值的类型脚本array.排序()

TypeORM QueryBuilder限制联接到一条记录