代码之家  ›  专栏  ›  技术社区  ›  Souad Guo Xiuhao

ngFor没有显示任何数据

  •  0
  • Souad Guo Xiuhao  · 技术社区  · 6 年前

    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变为空)。我不知道如何显示数据。。。变量 项目编辑 只有一个值(length=1),但因为它有一个名为 results 我通过for循环显示数据。当我尝试在typescript中执行类似操作时:

      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来填充数据库中的select字段。。。。 删除该请求后,我的代码工作正常。

    4 回复  |  直到 6 年前
        1
  •  0
  •   Alex Peters    6 年前

    你现有的 ngOnInit 方法有问题:

    1. this.id 之前 this.id 有机会被安排。
    2. 它不会更新 this.ItemToEdit 什么时候 this.id 变化。
    3. this.id 可能与当前加载数据的实际ID不匹配。

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

    1. 在发出HTTP请求之前,等待检索到ID,
    2. 仅更新 数据可用时 this.ItemToEdit ,和
    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> 模板中的某个地方允许您检查服务器的实际输出,这允许您识别来自服务器的频繁错误。

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

    根据您的需要,当出现以下错误时,您可能希望在页面上输出服务器错误:

    <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>
    
        2
  •  0
  •   Antoine Clavijo    6 年前

    尝试使所有进程保持异步

    <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'])
            );
        });
    }
    
        3
  •  0
  •   Vinko Vorih    6 年前
    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);
    }
    
        4
  •  0
  •   buzzwauld    6 年前

    首选的解决方案是 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();
      });
    }