0

我有一个关于 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 指令。我是否可以执行动态内容,以便使用Renderer2or应用我的指令(甚至在其自身内) ComponentFactoryResolver。我知道在 AngularJS 中我可以使用$compile,但在 Angular2 中我找不到任何关于如何解决我的问题的示例——只有如何注入组件,而不是带有 Angular 指令的 HTML 元素。这是可以实现的,还是我在追逐无法完成的事情?

4

0 回答 0