Я бы создал компонент с селектором атрибутов, который вы можете установить в div, который оборачивает ввод.Что-то вроде:
import { Component, Input } from '@angular/core';
@Component({
selector: 'div[wrapper]',
template: `
<label>{{labelText}}</label>
<ng-content></ng-content>
`,
styles: [`
:host {
border:thin solid;
padding:10px;
}
`]
})
export class WrapperComponent {
@Input() labelText: string;
}
и используйте его так:
<div wrapper [labelText]="'test text'">
<input type="text">
</div>
https://stackblitz.com/edit/attribute-selector-component?file=src%2Fapp%2Fwrapper.component.ts
Доступ к labelText
в шаблоне довольно прост.Вам просто нужно передать контекст (2-й параметр) в createEmbeddedView
({labelText: this.labelText}
).Вы также можете вставить шаблон в качестве первого потомка представления, передав индекс (3-й параметр) в createEmbeddedView
как 0.
https://angular.io/api/core/ViewContainerRef#createEmbeddedView
Если вы действительно хотите использоватьдиректива, это должна быть структурная директива, если вы хотите изменить положение элемента в DOM (добавьте обертку вокруг него).Таким образом, вы на самом деле получаете шаблон элемента и шаблон для оболочки, и ваша директива оборачивает их (конечно, вы также можете использовать службу шаблонов, если хотите ...):
import { Directive, Input, ViewContainerRef, TemplateRef, EmbeddedViewRef } from '@angular/core';
@Directive({
selector: '[wrapperLabelText]',
})
export class WrapperDirective {
private _labelText: string;
private embedded: EmbeddedViewRef<any>;
@Input('wrapperLabelText')
get labelText() {
return this._labelText;
}
set labelText(value: string) {
this._labelText = value;
if (this.embedded) {
this.embedded.context.labelText = value;
}
};
@Input('wrapperLabelTextWrapper')
wrapperTemplate: TemplateRef<any>;
constructor(
private templateRef: TemplateRef<any>,
private vc: ViewContainerRef,
) {
}
async ngAfterViewInit() {
await new Promise(resolve => setTimeout(resolve));
const ref = this.vc.createEmbeddedView(this.wrapperTemplate, {
wrapped: this.templateRef,
labelText: this.labelText,
});
}
}
ииспользуйте это как:
<input type="text" *wrapperLabelText="'test';wrapper:wrapperTemplate">
<input type="text" *wrapperLabelText="'test 2';wrapper:wrapperTemplate">
<ng-template #wrapperTemplate let-wrapped="wrapped" let-labelText="labelText">
<div style="border:thin solid; padding:10px">
<label>{{labelText}}</label>
<ng-container *ngTemplateOutlet="wrapped"></ng-container>
</div>
</ng-template>
https://stackblitz.com/edit/wrapper-directive?file=src/app/app.component.html