来自 Promise 的 Angular 4 显示元素

Posted

技术标签:

【中文标题】来自 Promise 的 Angular 4 显示元素【英文标题】:Angular 4 Display Elements from a Promise 【发布时间】:2018-02-08 09:00:20 【问题描述】:

我有以下 Typescript 服务 (app.component.ts):

import  Component, OnInit  from '@angular/core';
import  ApiService  from './shared/api.service';
import PowerPlant from './shared/models/powerplant.model';
import 'rxjs/add/operator/toPromise';

@Component(
  selector: 'app-root',
  providers: [ApiService],
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
)
export class AppComponent implements OnInit 
  // represents the URL's
  allPowerPlantsURL = 'powerPlants';
  // represents the data
  powerPlants: PowerPlant[];

  ngOnInit(): void 
    this.allPowerPlants();
  

  constructor(private apiService: ApiService) 
  

  allPowerPlants(onlyActive: boolean = false, page: number = 1): void 
    const params: string = [
      `onlyActive=$onlyActive`,
      `page=$page`
    ].join('&');
    const path = `$this.allPowerPlantsURL?$params`;
    this.apiService.get(path)
    .toPromise()
    .then(elem => 
    console.log('In the allPowerPlants');
    console.log(elem); **// prints undefined here**
    this.powerPlants = <PowerPlant[]> elem; 
  )
      .catch(this.handleError);
  

  private handleError(error: any): Promise<any> 
    console.error('An error occurred', error);
    return Promise.reject(error.message || error);
  

这是我的 app.component.html(只是其中的一个 sn-p):

<div class="ui grid posts">
  <app-powerplant
    *ngFor="let powerPlant of powerPlants"
    [powerPlant]="powerPlant">
  </app-powerplant>
</div>

现在,在我的 powerplant.component.html 中,我有这个:

从 '@angular/core' 导入 Component, Input, OnInit; 从'../shared/models/powerplant.model'导入PowerPlant;

@Component(
  selector: 'app-powerplant',
  templateUrl: './powerplant.component.html',
  styleUrls: ['./powerplant.component.css']
)
export class PowerplantComponent implements OnInit 

  @Input() powerPlant: PowerPlant;

  constructor()  

  ngOnInit() 
  

最后,应该显示 PowerPlant 项目的项目是这样的:

<div class="four wide column center aligned votes">
  <div class="ui statistic">
    <div class="value">
       powerPlant.powerPlantId 
    </div>
    <div class="label">
      Points
    </div>
  </div>
</div>
<div class="twelve wide column">
  <div class="value">
    MaxPower:  powerPlant.maxPower  MinPower:  powerPlant.minPower 
  </div>
  <div class="value">
    MaxPower:  powerPlant.maxPower  MinPower:  powerPlant.minPower 
  </div>
  <div class="value">
    PowerPlantType:  powerPlant.powerPlantType  Organization:  powerPlant.powerPlantName 
  </div>
</div>

我可以看到服务器正在向我发送数组,因为 get 方法上的以下控制台日志显示:

  get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> 
    console.log('sending request to ' + `$environment.api_url$path`);
    return this.http.get(`$environment.api_url$path`,  search: params )
      .catch(this.formatErrors)
      .map((res: Response) => 
        console.log(res.json());
        res.json();
      );
  

console.log 行在屏幕截图中显示以下内容:

那么为什么 toPromise() 会失败?仅供参考,我的 PowerPlant 模型如下所示:

export interface PowerPlant 
  powerPlantId: number;
  powerPlantName: string;
  minPower: number;
  maxPower: number;
  powerPlantType: string;
  rampRateInSeconds?: number;
  rampPowerRate?: number;

【问题讨论】:

【参考方案1】:

使用toPromise() 方法是否有特定原因?正常订阅时有效吗?

尝试更改此设置

this.apiService.get(path)
  .toPromise()
  .then(elem => 
  console.log('In the allPowerPlants');
  console.log(elem); **// prints undefined here**
  this.powerPlants = <PowerPlant[]> elem; 
)

到这里:

this.apiService.get(path).subscribe(result => 
    console.log('Im the result => ', result);
    this.powerPlants = <PowerPlant[]> result;
  );

那可能是因为您没有在 .map() 方法中返回解析结果,因此您无法在您的承诺/订阅中获得响应。

.map((res: Response) => res.json()); // return is inferred in this syntax


.map((res: Response) =>  
  return res.json(); // here it's not
);

【讨论】:

没有太大区别!这就是我得到的 - 我的结果 => 未定义 更新的答案,可能是这个。 是的!就是这样!凉爽的!感谢您的建议! 没问题!坚持下去!【参考方案2】:

和你的ApiService有关,你的.map忘记回res.json

  get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> 
console.log('sending request to ' + `$environment.api_url$path`);
return this.http.get(`$environment.api_url$path`,  search: params )
  .catch(this.formatErrors)
  .map((res: Response) => 
    console.log(res.json());
    return res.json();
  );

【讨论】:

以上是关于来自 Promise 的 Angular 4 显示元素的主要内容,如果未能解决你的问题,请参考以下文章

Angular2 Observable 和 Promise

Angular - 测试组件 - 从模拟返回 Promise.reject 时出错

使用 Promise 在 Angular 和 Ionic 的页面上显示用户信息时出现以下错误

angular ui-router 1.0.3 和 angular.js 1.6.4 似乎使用了错误的 Promise 类型?

Angular 5 - Promise vs Observable - 性能上下文

来自 node_modules 的 Angular 单元测试 spyOn 类