【问题标题】:Using getters in the Angular component html template在 Angular 组件 html 模板中使用 getter
【发布时间】:2020-07-24 04:17:30
【问题描述】:

我有一个数据模型类,比如说:

class Question {
    body: string;
    
    get bodyForTableRow(): string {
        return this.body.replace("\n", " // ");
    }
}

在组件 html 模板中,我使用以下声明来评估 getter 值:

 {{ oneQuestion.bodyForTableRow }}

但不是 value,而是用 // 符号替换新行,我得到一个空字符串。

当我使用时

 {{ oneQuestion.body }}

它显示正文内容。

为什么会这样?我是否应该始终使用 real 字段将它们映射到 html-components 和 getter 不适合这种情况?


更新

当模板中的声明看起来像这样时

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <!-- other columns skipped --> 

  <ng-container matColumnDef="body">
    <th mat-header-cell *matHeaderCellDef>Question Body</th>
    <td mat-cell *matCellDef="let oneQuestion">
      {{ oneQuestion.body }}
    </td>
  </ng-container>
</table>

它在每个表格行中显示body 内容。但是当我使用这段代码时:

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
  <!-- other columns skipped --> 

  <ng-container matColumnDef="body">
    <th mat-header-cell *matHeaderCellDef>Question Body</th>
    <td mat-cell *matCellDef="let oneQuestion">
      {{ oneQuestion.bodyForTableRow }}
    </td>
  </ng-container>
</table>

它显示空行。


更新 2

这样声明的问题数据模型类:

export class QuestionDataModel {
  body: string; // public access field for template
  
  constructor(bodyValue: string) {
    this.body = bodyValue;
  }  
  
}

数据源是这样声明的:

  dataSource: QuestionDataModel[];

我通过 rest-call 填充数据源

const url: string = `/questions/all`;
this.http.get(url).subscribe(
  (data: QuestionDataModel[]) => {
    this.dataSource = data;
  },
  (error) => this.reportServerError(error)
);

【问题讨论】:

  • 您实际上是在创建Question 类的实例吗?仅使用类型断言不会创建Question 的实例,并且您将无法访问getter/setters/其他方法。
  • @cjd82187 我已经发布了我的问题的更新。它澄清了吗?
  • @Rafael 不,更新没有说明,在这种情况下,我们需要看看您是如何获取和创建 dataSource 的。似乎那里正在发生可疑的事情。
  • @bryan60 我会尽快更新我的问题。谢谢。
  • @bryan60 我又更新了我的问题。

标签: angular typescript


【解决方案1】:

你正在做的事情应该可以工作,你还有其他一些问题,比如没有正确实例化你的类,但你可能真的想重组以使用 setter...

class Question {
    private _body: string;

    set body(body: string) {
      this.bodyForTableRow = body.replace("\n", " // ");
      this._body = body;
    }
    get body() {
      return this._body;
    }
    
    bodyForTableRow: string;
}

角度变化检测的工作方式是在每个变化检测周期上评估函数,这可能非常频繁,因此通过将 replace 放入 getter 中,您可以在每个周期中运行它。使用这种结构,您只需在需要时运行和设置它。

要使用这个或任何类,你需要使用new关键字,

this.oneQuestion = new Question();
this.oneQuestion.body = 'my string with line returns \n next line';

【讨论】:

  • 我的问题的重点是,我是否应该有一个“真实”字段来存储一个值,就像你声明的 bodyForTableRow: string 一样,或者有一个 getter 就足够了。据我了解,只有 getter,使用 body 字段计算其值不起作用。我应该将处理后的数据保存到另一个真实字段并使用它。我说的对吗?
  • 这两种方式都应该有效,但使用“真实”字段效率更高,性能也更好。你有另一个与你的 getter 无关的问题导致了问题。
  • 谢谢,我明白了,预先计算的字段应该表现更好。我只是想知道为什么这个吸气剂在我的情况下不起作用。我的方法有什么问题。我对 Java/C# 有一些经验,据我所知,如果我有一个类实例,我可以使用 getter 来获取基于这个类实例的计算值。为什么不在这种情况下?
  • 问题是您没有在任何地方使用new 关键字创建类实例。您只是在声明类型,它不起作用,您需要实际创建类。 TS 相信你的话,你不是在撒谎,但你确实在撒谎。
  • 因为 getter 是一个类特性,需要你实例化一个类。你没有一个类实例数组。您有一个对象数组,其中没有您期望的相关类功能,并且您对 typescript 的类型撒谎,
猜你喜欢
  • 1970-01-01
  • 2019-04-15
  • 2016-04-16
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
相关资源
最近更新 更多