我有一个关于 DOM 操作和指令的相当复杂的 Angular 问题——如果我的措辞不好或令人困惑,请告诉我,我会修改我的问题。
请注意,我已经降低了示例中的复杂性,以减少代码并在我的实际问题中获得概念证明。
例如,我有一个将 CSS 样式应用于按钮的 Angular 指令。像这样的东西...
@Directive({
selector: '[myCoolButton]'
})
export class CoolButtonDirective {
@Input() buttonStyle: string;
constructor(private elementRef: ElementRef) {}
ngOnInit(): void {
this.setButtonStyles();
};
setButtonStyles(): void {
if (this.buttonStyle === 'red') {
this.elementRef.nativeElement.classList.add('my-red-css-class');
}
if (this.buttonStyle === 'blue') {
this.elementRef.nativeElement.classList.add('my-blue-css-class');
}
if(!this.buttonStyle) {
this.elementRef.nativeElement.classList.add('my-default-css-class');
}
}
}
这是一个简化版本,我在其中添加了一个输入,而 logic/Input() 将确定按钮的外观。我会像这样在组件中实现按钮:
<button myCoolButton buttonStyle="blue">My Button Text</button>
现在说我想要花哨并让我的按钮/指令在单击时显示一个子菜单,并且这个我动态创建的 DIV 菜单充满了我想要包含/具有相同按钮指令的更简单的按钮。因此,假设我添加了称为菜单的 Input()。这是一个字符串数组,用于确定子按钮样式。因此,如果我将以下内容添加到我的指令中
<!-- notice default style -->
<button myCoolButton [menu]="[{text: 'button one', color: 'red'}, {text: 'button two', color: 'blue'}, {text: 'button three', color: 'red'}]">Menu</button>
我想在dom中输出的是:
<button class="my-default-css-class">Menu</button>
<div class="btn__menu btn__menu--hide">
<button class="my-default-red-class">button one</button>
<button class="my-default-blue-class">button two</button>
<button class="my-default-red-class">button three</button>
</div>
这样该指令就可以向 dom 添加新按钮并应用自己来设置菜单中按钮的 css。所以我修改了我的指令代码:
@Directive({
selector: '[myCoolButton]'
})
export class CoolButtonDirective {
@Input() buttonStyle: string;
@Input() menu: any[];
constructor(private elementRef: ElementRef) {}
ngOnInit(): void {
this.setButtonStyles();
if (this.menu) {
this.createMenu();
}
};
setButtonStyles(): void {
// same code as previous example... just saving space
}
createMenu(): void {
const menuDiv = document.createElement('div');
menuDiv.classList.add('btn__menu', 'btn__menu--hide');
this.elementRef.nativeElement.after(menuDiv);
// add a click event to toggle the show and hide!
this.elementRef.nativeElement.addEventListener('click',
() => this.elementRef.nativeElement.nextElementSibling.classList.toggle('btn__menu--hide'), true);
// now loop through the menu array to create buttons within the new menu div
this.menu.forEach((menuItem: any) => {
const button = document.createElement('button');
button.innerHTML = menuItem.text;
button.setAttribute('myCoolButton', ''); // add directive to apply styles
button.setAttribute('menu', menuItem.color): // set the input to determine value of child/menu button
menuDiv.appendChild(button);
});
}
}
现在虽然这会附加到我创建的菜单中,但子/菜单按钮将是默认按钮,并且没有应用我的 Angular 指令。我是否可以执行动态内容,以便使用Renderer2
or应用我的指令(甚至在其自身内) ComponentFactoryResolver
。我知道在 AngularJS 中我可以使用$compile
,但在 Angular2 中我找不到任何关于如何解决我的问题的示例——只有如何注入组件,而不是带有 Angular 指令的 HTML 元素。这是可以实现的,还是我在追逐无法完成的事情?