【问题标题】:Trying to add a computed property to a result set from a controller in Angular尝试从 Angular 中的控制器将计算属性添加到结果集中
【发布时间】:2019-12-23 21:28:02
【问题描述】:

我正在使用 Angular 8,并且正在尝试做一些看起来应该非常简单的事情。

我正在使用 http.get 从服务器上的控制器检索一组记录。这些记录具有特定类型(在 Angular 中定义),我想为该类型添加一个计算属性,称为“meetsTarget”。我的问题是它没有认识到我从服务器返回的结果中存在该属性。

问题 2: 因为该属性是根据其他属性计算的,所以我还希望在其他属性发生更改时对其进行更新(并且这些更新会自动在 html 中获取)。

这是我的组件:

import { Component, Inject } from '@angular/core';
import { Location } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { ActivatedRoute } from "@angular/router";
import { Globals, KPIEntry } from './../../globals';

@Component({
  selector: 'app-enter-toller',
  templateUrl: './enter-toller.component.html',
  styleUrls: ['./enter-toller.component.css']
})
export class EnterTollerComponent {
  public data: KPIEntry[];

  constructor(private route: ActivatedRoute, private http: HttpClient, @Inject('BASE_URL') private baseURL: string, private gl: Globals, private location: Location) {
    // get results from the server
    this.http.get<KPIEntry[]>(this.baseURL + 'api/KPIEntry/ListTollerKPI/1').subscribe(result => {
      this.data = result;
      console.log(this.data);
    }, error => console.error(error));
  } 
}

我对上述代码的问题是,当我将 this.data 记录到控制台时,我可以看到来自服务器的所有结果,但它没有显示我的计算属性“meetsTarget”。

KPIEntry(连同我的计算属性“meetsTarget”)在 globals.ts 中定义:

export class KPIEntry {
  id: number;
  kpiName: string;
  mtd: number;
  ytd: number;
  targetYTD: number;
  kpiComparisonType: string;

  get meetsTarget(): boolean {
    if (this.kpiComparisonType == "gteq") {
      return (this.ytd >= this.targetYTD);
    }
    if (this.kpiComparisonType == "lteq") {
      return (this.ytd <= this.targetYTD);
    }
  }
}

如您所见,metesTarget 是一个只读属性,它依赖于 kpiComparisonType、ytd 和 targetYTD。可以使用上面的组件同时更改 ytd 和 targetYTD,因此如果这些值中的任何一个发生更改,则 meetTarget 的结果应该是动态更新的。

我的第一个问题是,我什至无法将“meetsTarget”识别为结果集中记录的属性。

如果有人能指出我正确的方向,我将不胜感激。

谢谢!

【问题讨论】:

    标签: angular controller angular8 computed-properties


    【解决方案1】:
    this.http.get<KPIEntry[]>
    

    这告诉 TypeScript:相信我,这个调用将返回一个 Observable&lt;KPIEntry[]&gt;

    它确实告诉:请从服务器获取 JSON 并将其解析为 KPIEntry 的数组。

    HttpClient 对它得到的 JSON 响应体所做的事情非常简单:它调用JSON.parse()。解析 JSON 永远不会产生您的类的实例。 JSON 解析器不知道您的类存在并且不关心它。它只是创建与 JSON 具有相同结构的普通旧 JavaScript 对象。

    所以当你这样做时

    this.http.get<KPIEntry[]>
    

    你只是在对编译器和你自己撒谎。

    如果您想拥有KPIEntry 的实例,您需要通过调用类构造函数来创建它们。因此,您需要将数组中的每个 POJO 转换为可观察对象实际发出的一个实例KPIEntry

    【讨论】:

    • 谢谢,这有帮助。你能提出比这更有效的方法吗? this.http.get(this.baseURL + 'api/KPIEntry/ListTollerKPI/1').subscribe(result => { this.data = []; result.forEach(r => { this.data .push(new KPIEntry(r)); }); //console.log(this.data); }, error => console.error(error));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 2016-04-04
    • 2014-05-26
    相关资源
    最近更新 更多