我在我的应用程序中创建了一个组件,用作输入标签的包装器(我在制作自己的UI库很有趣)。我的组件将像这样使用。
<sio-input [label]="'Sio Input Label'">
<input type="text" name="">
</sio-input>
这样做的目的是动态添加CSS类和功能,因此开发人员不必这样做。这是我的组件(为了便于阅读,我已经按比例缩小了代码)
@Component({
selector: 'sio-input',
templateUrl: './input.component.html', // only contains <ng-content></ng-content>
styleUrls: ['./input.component.scss'],
})
export class InputComponent implements OnInit {
@Input() label: string;
// this component used Render2 - https://angular.io/api/core/Renderer2
constructor(private elRef: ElementRef, private renderer: Renderer2) {
}
ngOnInit() {
// if a label exist prepend it to the HTML
if (this.label) {
const formInput = this.elRef.nativeElement.querySelector('input');
const appendLabel = this.renderer.createElement('LABEL');
const textNode = this.renderer.createText(this.label);
this.renderer.addClass(appendLabel, 'sio-input__label');
this.renderer.appendChild(appendLabel, textNode);
this.renderer.insertBefore(this.elRef.nativeElement, appendLabel, formInput);
// add the directive
this.renderer.setAttribute(formInput, 'sioInput', null);
}
}
}
@Directive({
selector: '[sioInput]'
})
export class SioInputDirective {
@HostListener('focus', ['$event.target'])
onFocus(event) {
console.log('Boom! We Have Focus');
}
}
如您所见,我希望向在组件DOM中找到的formInput
动态添加属性指令。遗憾的是,这无法正常工作,因为renderer.setAttribute
呈现的输出采用了“ sioInput
”属性名称并将其呈现为“ sioinput
”,因此Angular无法识别该属性指令。我是否应该在输入中的模板HTML中手动放置指令名称,自然一切正常-但我希望它是动态的。我究竟做错了什么?如何在不将名称转换为小写的情况下动态设置属性指令。
在此先感谢您-如果我不能很好地解释我的问题或感到困惑,请这样说,我将重述我的问题。
答案 0 :(得分:0)
Angular是一种编译语言:您编写TS,将其转换为JS。
装饰器中的选择器是构建前:不能在构建后中应用。
这意味着您不应使用渲染器(它将执行 post-build ),而应使用模板本身来管理角度组件。
作为旁注,组件中的指令通常是组件使用@ContentChild
通过<ng-content>
管理内容的一种方式。除了将自定义类添加到elementRef
中,以及可能实现控件值访问器之外,该指令并没有做什么用。
我建议您看看Material Input Elements或PrimeNG来了解它们的用法,因为它们被广泛使用并且通常也很容易使用!