如何在Angular 9中访问组件的唯一封装ID

12

我试图通过添加实例ID来封装我的元素ID,像这样:

<label for="id-{{ unique }}-name"></label>
<input id="id-{{ unique }}-name" type="text" formControlName="name">

我以前使用过这个:https://dev59.com/9pvga4cB1Zd3GeqP68bd#40140762。 但是在将 Angular 从7升级到9后,它似乎已经过时了。 我正在考虑编写一个简单的助手服务,为我的应用程序生成唯一标识符。

类似于这样:

@Injectable()
export class UniqueIdService {
  private counter = 0

  constructor() {}

  public getUniqueId (prefix: string) {
    const id = ++this.counter
    return prefix + id
  }
}

受 lodash uniqueid 启发

但我更倾向于使用 Angular 内置的 id。目前我的解决方案是从组件的 _nghost 属性中提取 id。

constructor ( private element: ElementRef, ) {
   const ngHost = 
     Object.values(this.element.nativeElement.attributes as NamedNodeMap)
     .find(attr => attr.name.startsWith('_nghost'))
     .name
   this.unique = ngHost.substr(ngHost.lastIndexOf('-') + 1)
}

但是我对这个解决方案并不完全满意,我正在寻找直接访问该id的方法。

有人知道如何访问它吗?

3个回答

10
Angular 9中的唯一ID可以表示为:
_nghost   -   par    -     2
   |           |           |
 static      APP_ID   componentDef.id
为了访问 componentDef.id,您可以执行以下操作:
export class SomeComponent implements OnInit {
  unique = this.constructor['ɵcmp'].id;

ɵcmp是一个私有变量,NG_COMP_DEF指向它。

Ng-run的示例


6
既然这是私有的,我们应该避免使用它……否则的话它本来就应该是公共 API 的一部分,对吧? - Georgi
5
只有当组件只有一个实例时,这才有效。基本上,它是组件的 ID,而不是组件实例 ID,因此在渲染多个相同类型的组件时,它不会是唯一的。 - Canica
1
@Canica - 我认为组件的所有实例共享相同的封装 ID。至少,在我的 Angular 页面上有多个实例时,我看到的就是这样。 - ConnorsFan
1
使用您的示例,您可以复制并粘贴子组件,它们都具有相同的ID。这不是唯一的,也不安全。 - Kody

4

虽然这个链接可能回答了问题,但最好在此包含答案的必要部分,并提供参考链接。如果链接页面发生更改,仅有链接的答案可能会失效。- 来自审核 - Nol4635
这不仅仅是链接。该函数返回解决问题的唯一ID。 - Petr Pavlov

1

_nghostɵcmp都不是在组件实例中唯一的。它们不应该用于此目的。

您的UniqueIdService是最简单和最安全的解决方案。(counter属性可以是静态的,以确保服务的每个实例返回唯一的ID)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接