以下是一个将任意属性应用于容器的所有直接子级的指令:
@Directive({
selector: '[setAttributes]',
})
export class SetAttributesDirective {
@Input('setAttributes') atts: { [key: string]: string } = {};
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) {}
ngOnInit() {
const keys = Object.keys(this.atts);
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
for (const node of viewRef.rootNodes) {
if (typeof node.setAttribute !== 'function') continue;
const el = node as HTMLElement;
for (const key of keys) el.setAttribute(key, this.atts[key]);
}
}
}
不是很安全,因为viewRef.rootNodes
是any[]
,但你能做什么…我放了一个防打字.第一个条目实际上是ng-container
本身,嵌套的模板/ng容器也没有setAttribute
函数,在没有typeguard的情况下抛出错误.当然可以改进,但至少你知道要点.
你可以这样使用它:
<ng-container *setAttributes="{ type: 'number', value: '5', min: '0', max: '10' }">
<input />
<input />
<input />
<input />
</ng-container>
关联单据:https://angular.io/guide/structural-directives
Stackblitz示例:https://stackblitz.com/edit/angular-ivy-1eyjlo?file=src/app/app.component.html
对于您的示例,您需要从DOM node 获取组件实例.有一个用于调试的函数,但不确定为什么它不是常规API的一部分:https://angular.io/api/core/global/ngGetComponent
您必须告诉tsc该函数存在,然后您可以设置组件的属性:
declare global {
interface Window {
ng: { getComponent: (el: Element) => { [key: string]: any } | null };
}
}
@Directive({
selector: '[setInputs]',
})
export class SetInputsDirective {
@Input('setInputs') atts: { [key: string]: any } = {};
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) {}
ngOnInit() {
const keys = Object.keys(this.atts);
const viewRef = this.viewContainer.createEmbeddedView(this.templateRef);
for (const node of viewRef.rootNodes) {
if (!(node instanceof Element)) continue;
const component = window.ng.getComponent(node);
if (component === null) continue;
for (const key of keys) component[key] = this.atts[key];
}
}
}
<ng-container *setInputs="{ labelKeyBase: 'MODULE.PAGE_X', validationKeyBase: 'VALIDATION.CUSTOM_X' }">
<yes-no controlName="isAwesome"></yes-no>
<yes-no controlName="isClean"></yes-no>
<yes-no controlName="isShort"></yes-no>
</ng-container>
Stackflash:https://stackblitz.com/edit/angular-ivy-mbcw9o?file=src/app/app.component.html