【问题标题】:How to render placeholder template attributes on page如何在页面上呈现占位符模板属性
【发布时间】:2023-03-26 01:05:01
【问题描述】:

我正在构建一个 Angular 9 应用程序。 在这个应用程序中,我让我的用户以文本形式将“占位符”保存到数据库中。

我想呈现这些占位符,但在渲染时将其替换为真实数据。

例如。保存数据的对象称为模型,所以通常我会在页面上显示这样的数据,显示用户名。

{{model.fullname}}

基本上我想将这个占位符保存到数据库中,然后渲染它。所以我的问题是如何让 {{model.fullname}} 在呈现页面时“激活”,即使它来自数据库/JSON 而不是硬编码到页面中。

更新

我尝试了下面发布的 Pipe 建议,它确实有效。问题是它单独打印真实数据,而不是在较大字符串内的上下文中。换句话说,我需要将文本中的占位符值替换到它们在字符串中的真实位置。

这是管道代码:

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
  name: 'template',
})
export class TemplatePipe implements PipeTransform {
  transform(value: string, args: any): any {
    if (value.indexOf('.name') !== -1) {
      return args.name;
    }
    if (value.indexOf('.id') !== -1) {
      console.log(args.id);
      return args.id;
    }
    return null;
  }
}

这是我想使用的典型文本:

The name of the user is {{model.name}} and got the ID of {{model.id}}.

结果必须是:

The name of the user is Paul Palmer and got the ID of 123456.

【问题讨论】:

标签: angular


【解决方案1】:

一个简单的解决方案是使用管道

例如,你有一个类似的对象

export class Candidate{
    public id: number;
    public name: string;
}

并且您想将密钥存储在数据库或 json 文件或其他任何内容中(关键是它们将被动态呈现),以说明我的密钥存储在这样的组件中的变量中

public key: string = "{{candidate.name}}";

现在我创建了一个管道,它将检查键并返回相应的对象属性,如下所示。

export class TransformkeyPipe implements PipeTransform {
  transform(value: any, args: any): any {
if (value == "{{candidate.name}}") {
  return args.name;
}
if (value == "{{candidate.id}}") {
  return args.id;
}
return null;
  }
}

在组件文件中,我将应用管道以及具有数据的实际对象。像这样的

<p>{{key | transformkey: candidate}}</p>

编辑:

如果您想替换字符串中的 placeholders,那么您只需使用 javascript ma​​tch 函数使用一些正则表达式来提取占位符。然后用实际数据一一替换。像这样。

export class Transformkey2Pipe implements PipeTransform {
  transform(value: string, args: any): any {
const regexp = /{{[a-z]*.[a-z]*}}/g;
const array: string[] = value.match(regexp);

array.forEach(x => {
  switch (x) {
    case "{{candidate.name}}":
      value = value.replace(x, args.name);
      break;
    case "{{candidate.id}}":
      value = value.replace(x, args.id);
      break;
  }
});

return value;
}
}

编辑 2 如果您想使用多个数据源,一种方法可能是将 objectType 参数传递给您的管道,并据此决定选择哪个数据源字段。像这样的

export class Transformkey3Pipe implements PipeTransform {
  transform(value: string, args: any, objectType: string): any {
const regexp = /{{[a-z]*.[a-z]*}}/g;
const array: string[] = value.match(regexp);

array.forEach(x => {
  switch (x) {
    case "{{key.name}}":
      if (objectType == "candidate") {
        value = value.replace(x, args.name);
      }
      if (objectType == "employee") {
        value = value.replace(x, args.emp_name);
      }
      break;
    case "{{key.id}}":
      if (objectType == "candidate") {
        value = value.replace(x, args.id);
      }
      if (objectType == "employee") {
        value = value.replace(x, args.emp_id);
      }
      break;
  }
});

return value;
  }
}

请查找更新后的stackblitz

【讨论】:

  • 非常有趣!几乎正是我需要的。但有一件事,它永远不会单独匹配例如 {{candidate.name}},但此变量始终是较大字符串的一部分,例如:“用户的名称是 {{candidate.name}}”。我如何才能将您的 Pipe 与仅 {{candidate.name}} 单独的更大字符串一起使用?
  • 换句话说。如何使用您的管道替换较大文本中的主题占位符?
  • 完美运行!最后一件事,是否可以让它更具动态性,这样我就不必使用开关了?就像如果 {{candidate.id}} 包含 .id 它总是会返回 args.id?
  • 您的意思是键可以从多个数据源中提取值。在这种情况下,您可以将第三个参数传递给提及对象类型的管道,例如它的名称是“objectType”。因此,例如,您可以说 if(objectType=='candidate') 然后使用 args.id if(objectType=='employee') 然后使用 arge.emp_id 等。
  • 太棒了,这正是我需要的!非常感谢!
猜你喜欢
  • 1970-01-01
  • 2018-01-08
  • 2013-10-18
  • 2015-05-21
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
相关资源
最近更新 更多