繁体   English   中英

ngFor没有显示任何数据

[英]ngFor is not showing any data

我正在尝试使用Angular 6将一些数据绑定到模板,所以这是ngOnInit

ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
        this.id = +params['id'];
    });
    let url = this.baseUrl + `/items/${this.id}`;
    this.httpClient.get(url).subscribe((data : Array<any>)=> {
        this.ItemToEdit = data;
    });
}

这是模板:

<div *ngFor="let item of ItemToEdit?.results">
              <div class="col-sm-8 float-left">

                <mat-form-field> <input matInput
                  class="form-control" placeholder="Item name"
                  formControlName="name" id="ItemName" value='{{ item.name }}'>
                </mat-form-field>

              </div>
</div>

变量ItemToEdit如下所示:

{
  "results": [
    {
      "alias": [
        "first"
      ], 
      "apps": [], 
      "description": "this is an item", 
      "id": 1, 
      "name": "item342"
    }
  ]
}

因此,问题是当我打开模板(通过某个按钮)时,具有ngFor指令的HTML不显示(具有ngFor的div变为空白)。 我不知道如何显示数据...变量ItemToEdit仅具有一个值(长度= 1),但是由于它具有称为results的嵌套数组,因此我通过for循环显示数据。 当我尝试在打字稿中执行以下操作时:

  this.loadedName = this.ItemToEdit.results[0].name;

我收到一条错误消息,指出ItemToEdit.results

有任何想法吗?

编辑

发现我的代码有效,但仅在刷新页面后才能执行...

服务器间歇性地返回这样的响应,而不是预期的结果:

  • { "error": "(_mysql_exceptions.OperationalError) (2006, 'MySQL server has gone away') [SQL: 'SELECT .... }
  • { "error": "(_mysql_exceptions.ProgrammingError) (2014, \\"Commands out of sync; you can't run this command now\\") [SQL: 'SELECT ......" }

===============编辑2 ===============

我收到Mysql异常是因为我正在ngOnInit内进行另一个httpRequest来填充数据库中的选择字段...。删除该请求后,我的代码可以正常工作。

尝试使所有过程保持异步

<div *ngFor="let item of (itemToEdit$ | async)">
    <div class="col-sm-8 float-left">

    <mat-form-field> <input matInput
      class="form-control" placeholder="Item name"
      formControlName="name" id="ItemName" value='{{ item.name }}'>
    </mat-form-field>

    </div>
</div>

在您的组件中:

private itemToEdit$: Observable<any>;

....

ngOnInit() {
    this.route.params.subscribe(params => {
        this.id = +params['id'];
        let url = this.baseUrl + `/items/${this.id}`;
        this.itemToEdit$ = this.httpClient.get(url).pipe(
          map(data => data['results'])
        );
    });
}
test: any = [];  
ngOnInit() {
        this.service.test().subscribe(res => {
          this.test = res.results;
        });

HTML:

 <p *ngFor="let test of this.test">
   {{test.name}}
 </p>

如果需要将其绑定到输入字段,只需为其分配: [value]="test?.name"

服务:

test(): Observable<any>{
return this.http.get(url);
}

您现有的ngOnInit方法存在问题:

  1. 它读取this.id之前this.id必须设置一个机会。
  2. this.id更改时,它不会更新this.ItemToEdit
  3. this.id可能与当前加载的数据的实际ID不匹配。

以下建议的实现通过以下方法解决了这些问题:

  1. 在发出HTTP请求之前,等到ID检索完毕,
  2. 仅当this.id有可用数据时,才更新this.ItemToEdit ;以及
  3. 如果ID在完成之前发生更改,则取消所有未决的HTTP请求。
ngOnInit() {
    let itemToEditID;
    const httpObservable = this.route.params.pipe(
        map(params => +params['id']),
        tap(newID => itemToEditID = newID),
        switchMap(newID => this.httpClient.get(`${this.baseUrl}/items/${newID}`))
    );
    this.sub = httpObservable.subscribe(data => {
        this.id = itemToEditID;
        this.ItemToEdit = data;
    });
}

放置<pre>{{ ItemToEdit | json }}</pre> <pre>{{ ItemToEdit | json }}</pre>模板中的某个位置,您可以检查服务器的实际输出,从而可以确定服务器经常出现的错误。

关于这些错误的好消息是它们是由服务器而不是您的代码引起的。 坏消息是,您需要确定服务器出了什么问题以及如何解决该问题,但这是另一个问题。

根据您的需求,您可能希望在发生以下情况时在页面上输出服务器错误:

<div *ngIf="ItemToEdit?.error" class="danger">
    <h2>An error occurred while trying to retrieve item {{ id }}</h2>
    <p>{{ error }}</p>
</div>
<div *ngFor="let item of ItemToEdit?.results">
    <!-- ... -->
</div>

首选的解决方案是使用antoine-clavijo答案中定义的async

另外,如果您的组件(或父组件)是使用ChangeDetectionStrategy.OnPush定义的,例如:

@Component({
  selector: 'app-component',
  templateUrl: './config.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush
})

...您可以告诉Angular需要更新组件,如下所示:

constructor(
  private ref: ChangeDetectorRef, 
  private httpClient: HttpClient) {}

ngOnInit() {
  this.sub = this.route.params.subscribe(params => {
    this.id = +params['id'];
  });
  const url = this.baseUrl + `/items/${this.id}`;
  this.httpClient.get(url).subscribe((data: Array<any>)=> {
    this.ItemToEdit = data;
    this.ref.detectChanges();
  });
}

暂无
暂无

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

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