【问题标题】:Load data before Template gets loaded在加载模板之前加载数据
【发布时间】:2017-10-27 10:24:10
【问题描述】:

我有一个这样的模板

Component.html

    <h1>aditya</h1>
    <div class="row">
    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
      <table class="table table-bordered">
        <thead>
          <tr>
            <th style="white-space: nowrap" *ngFor="let columns of data?.display_columns; let i = index">{{columns}}</th>
          </tr>
          <tr *ngFor="let row1 of data?.row1; let i= index">
            <td style="white-space: nowrap" *ngFor="let columns of data?.display_columns; let i = index">{{row1[columns]}}</td>
          </tr>
        </thead>
      </table>
    </div>
  </div>  

Component.ts

import { Component, OnInit } from '@angular/core';
import { HttpModule } from '@angular/http';
import { SpreadsheetService } from '../dataservice/spreadsheet.service';

@Component({
    moduleId: module.id,
    selector: 'sd-list-view',
    templateUrl: 'list-view.component.html',
    styleUrls: ['list-view.component.css'],
    providers: [HttpModule, ListService]

})

export class ListViewComponent implements OnInit {
    data: any;
    spreadsheet: any;
    data1: any;
    isDataAvailable: boolean = false;
    constructor(public _spreadsheetService: SpreadsheetService) {
    }
ngOnInit() {
    this._spreadsheetService.getData()
        .subscribe(data => {
            this.data = data;
            (<any>window)['mydata'] = (data);
            console.log(this.data.display_columns);
            var data1: any;
            //alert('get data');
            return this.data;
        });
    //alert('list view 2');
    }
}

模板“Aditya”的第一行正在显示,但循环内的数据表未加载到组件初始化中。

如何在视图初始化之前运行循环并加载数据,或者在视图初始化之后加载表数据?
PS:循环已经过测试并且可以正常工作。我不想使用 APP_Initializer。
I have gone through this question 但无法理解解决方案,因为我使用的是 Observables 而不是 Promise。 提前致谢。

【问题讨论】:

  • 链接问题的哪一部分你不明白?
  • @GünterZöchbauer 我无法理解您在等待承诺首先加载的答案中的这一行 - “ngOnInit() { this.fetchEvent().then(() => console.log( this.ev)); // Now has value; }" 如果我​​必须做同样的事情,即在模板渲染之前等待 Observable 加载并返回数据,在我的情况下怎么做?
  • 只需使用subscribe() 而不是then()
  • 您传入的数据实际上是什么样的?

标签: angular


【解决方案1】:

您可以使用

包装模板的内容
<ng-container *ngIf="data">
 template content here
</ng-container>

如果你使用的是路由器,你可以使用resolver

如果你想在 AppComponent 初始化之前加载数据,你可以使用How to pass parameters rendered from backend to angular2 bootstrap method

【讨论】:

  • 你能告诉我一个使用 ngIf 的 plunker 吗?什么是数据?
  • data 是获取分配数据的字段。当data 变为 != null 时,模板的内容变为可见,因为*ngIf 条件变为真
【解决方案2】:

由于您的数据未定义,它将显示一些错误,例如“无法读取未定义的数据”。您的视图已初始化,但由于您的请求 spreadsheetService.getData() 是异步请求,因此稍后会给出响应。

您可以使用检查变量:

public isLoaded=false;

并且在您的 getData() 请求的订阅者中将该布尔值设为 true:

 this._spreadsheetService.getData()
    .subscribe(data => {
        this.isLoaded=true;
        this.data = data;
    });
}

在 html 中:

<div *ngIf="isLoaded">
//Your content
</div>

另一种可以避免的方法是检查,最初只需将数据声明为空数组,以便在循环时不会在开始时打印任何内容。

  data: Array<any>=[];

如果您想在视图初始化之前加载数据,请使用解析器。他们解决您的服务请求,并在收到响应后初始化视图。

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { MyService } from './my-service.ts';

@Injectable()
export class MyResolver implements Resolve<any> {

   constructor(private myservice: MyService) {}

  resolve(route: ActivatedRouteSnapshot) {
   return this.myservice.getData();
  }
}

在提供程序中添加此解析器,就像在服务中一样。并将该解析器添加到您的路由中,例如:

{
    path: 'mypath', component: MyComponent,
    resolve: {
      myData: MyResolver
    }
  },

【讨论】:

  • 我没有收到任何错误。当我在 ngFor 循环上不使用带有变量的 Elvis (?) 运算符时看到一个未定义的错误让我试一试你的答案。
  • 那么在这种情况下,如果您在视图初始化之前需要数据,您可以使用解析器。在上面的答案中给你一个示例代码
  • 刚刚试过这个解决方案。不幸的是,它仍然是一样的。每次都会调用数据,我可以在日志中看到它。但不渲染
  • 我在上面的评论中添加了在视图初始化之前加载数据的方法。希望对您有所帮助
猜你喜欢
  • 1970-01-01
  • 2018-02-08
  • 2019-05-28
  • 1970-01-01
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 2018-04-20
  • 1970-01-01
相关资源
最近更新 更多