在 Angular 2 组件中复制"id"属性



上下文

我正在为一个复选框编写一个自定义的Angular组件。组件将呈现复选框标记和标签标记。复选框的"id"属性和标签的"for"属性都设置为组件的id属性(组件的@Input),以确保单击标签将切换复选框。模板的简化版本如下:

<div class="checkbox">
<input type="checkbox" [id]="id" />
<label [for]="id"><ng-content></ng-content></label>
</div>

问题

当我在我的组件(例如<my-checkbox id="hello">Check me</my-checkbox>)上设置"id"道具时,DOM中的组件包装标签上会自动设置一个"id"属性。这会导致DOM中的id重复,因为我已经在组件内部的复选框上设置了"id"属性。这是无效的,并通过单击标签行为来打断浏览器的默认切换。DOM输出为:

<my-checkbox id=“my-checkbox” ng-reflect-id=“my-checkbox” ng-reflect-checked="true">
<div ng-reflect-ng-class="[object Object]" class="checkbox">
<input class="checkbox__element" type="checkbox" name="fire_missiles" ng-reflect-id=“my-checkbox” id=“my-checkbox” value=“fire_missiles” ng-reflect-checked="true">
<label class="checkbox__label" ng-reflect-html-for=“my-checkbox” for=“my-checkbox”>
Fire missiles?
</label>
</div>
</my-checkbox>

有没有办法a)去掉垃圾容器标记,或者b)停止将"id"道具作为属性自动反射到容器上?

注意:将属性选择器应用于类似div的东西并没有帮助,它只是将额外的"id"从<my-checkbox />移动到div。

我只需重命名复选框的id(以及标签的for属性),这样它就不会与组件的id冲突,如下所示:

<input id="{{ id }}-checkbox" …>
<label for="{{ id }}-checkbox">…</label>

您可以将id作为表达式传递:

<my-checkbox [id]="'hello'">Check me</my-checkbox>

在这种情况下,组件标记在DOM中不包含id属性,它只包含属性ng-reflect-id,这不会影响标签的默认行为。

这更像是一次黑客攻击,在你的组件上你可以这样做:

constructor(elementRef: ElementRef) {
elementRef.nativeElement.removeAttribute("id");
}

这应该会消除你在<my-checkbox></my-checkbox>上的id

我也遇到了类似的问题。我在ID之前添加了#符号,并使用ngModel绑定属性

<input id="#{{ id }}-checkbox" …>
<label for="#{{ id }}-checkbox">…</label>

最新更新