我正在使用Angular Material样式将按钮组件(AddButtonComponent
)动态地附加到另一个组件(ParentComponent
)的DOM上。如果我通常使用<button matButton>A button</button>
在模板中创建按钮,则按钮的样式会完美。如果我动态创建它,它也会被设置样式。
现在,我需要注入一个字符串以将类名附加到我的按钮上,但是如果使用自定义Injector
,它将丢失所有样式。我认为当我注入字符串时,它会覆盖该注入器当前的应用注入。
我尝试将ParentComponent
注入器添加到parent
属性中,但是也没有用。
我在做什么错了?
(很明显,我可以调用instance
中的ElementRef
并设置属性值,但这很丑陋。我相信可以实现。)
这是一个代码示例:
import {
Component,
OnInit,
Optional,
Inject,
Injector,
InjectionToken,
ElementRef,
ViewContainerRef,
ComponentFactoryResolver,
} from '@angular/core';
export const CLASS_INJECTION: InjectionToken<string> = new InjectionToken<string>('ClassInjection');
@Component({
selector: 'app-add-button`,
template: '<button matButton [class]="classInjection">A button</button>',
styles: []
})
export class AddButtonComponent implements OnInit {
constructor(@Optional() @Inject(CLASS_INJECTION) public classInjection: string) { }
}
@Component({
selector: 'app-parent-component',
template: '<button matButton>Button styled</button>',
styles: []
})
export class ParentComponent implements OnInit {
constructor(
private _injector: Injector,
private componentFactoryResolver: ComponentFactoryResolver,
private viewContainerRef: ViewContainerRef
) { }
ngOnInit() {
const addButtonComponentFactory = this.componentFactoryResolver.resolveComponentFactory(AddButtonComponent);
const addButtonComponentRef = this.viewContainerRef.createComponent(addButtonComponentFactory, undefined, Injector.create({
providers: [{provide: ELEMENT_TYPE, useValue: widget.type === 'column' ? 'SECTION' : 'MODULE'}],
parent: this._injector
}));
// <Code to add element into DOM...>
}
}
答案 0 :(得分:1)
<button matButton [class]="classInjection">A button</button>
matButton
在创建时将分配CSS类,但是您使用的[class]
绑定将替换所有现有的CSS类。因此,材料设计CSS样式丢失了。如果您在Chrome检查器中查看,则会看到它们已被删除。
如果您知道仅使用SECTION
和MODULE
,请使用[class.style]
绑定来选择性地添加或删除特定样式。
<button matButton [class.SECTION]="classInjection === 'SECTION'"
[class.MODULE]="classInjection === 'MODULE'">A button</button>
如果您不知道CSS样式是什么,则必须手动添加它们。可以通过通过<button>
访问@ViewChild
元素,然后手动添加CSS样式来完成。
@Component({
selector: 'app-add-button',
template: '<button matButton>A button</button>',
styles: []
})
export class AddButtonComponent implements OnInit {
@ViewChild(MatButton, {read: ElementRef})
public btn: ElementRef<HTMLElement>;
constructor(@Optional() @Inject(CLASS_INJECTION) public classInjection: string) {
}
public ngOnInit(): void {
this.btn.nativeElement.classList.add(this.classInjection);
}
}
过去使用[class]
时我感到非常沮丧,因为它会覆盖alls样式,并且没有其他替代方法可以使用。 [class]
和[ngClass]
的行为相同,如果必须频繁执行上述操作,则可以编写一个名为[addClass]
的自定义指令,该指令仅附加CSS样式。