提问人:Felice Lombardi 提问时间:11/17/2023 更新时间:11/17/2023 访问量:19
使用指令显示 <ng-template> 它在 angular 模板中的位置
Show <ng-template> where it is located in angular template using a directive
问:
我正在创建一个 Angular 指令,用于元素以显示 .<input type='text' formControlName="queryInput">
formControl
这个想法是:
如果将 an 传递给指令,则它应使用提供的模板来显示错误消息,并将模板定位在声明它的位置。
[errorTemplateRef]="errorTemplate"
如果提供了 no,则指令应在输入元素后添加一个简单的右键。
errorTemplateRef
<div>Validation error</div>
我在实现第 2 点时没有问题。但是,我遇到了第 1 点的问题。 我无法弄清楚如何在通过指令向其传递上下文(错误消息)时“呈现”模板。
你能帮我解决这个问题吗?
Angular 模板:
<form
[formGroup]="formGroup"
(ngSubmit)="onSubmitSearch()"
class="flex w-full shadow-default"
>
<input
formControlName="queryInput"
type="text"
class="w-full h-full border-0 bg-white rounded-l-md"
appInput
[showError]="showError"
[errorTemplateRef]="errorTemplate"
/>
<button
type="submit"
class="flex justify-center items-center w-29 ml-1 p-3 bg-white rounded-r-md"
>
<span class="w-3/6 text-blue font-semibold text-sm tracking-wide uppercase">Cerca</span>
<app-icon
class="w-3/6 text-indaco"
name="mdi:magnify"
size="16"
></app-icon>
</button>
</form>
<ng-template
#errorTemplate
let-message
><p class="text-crimson-red">Error: {{ message }}</p>
</ng-template>
appInput 指令 - 此时它用一个简单的 ,但我想使用它
@Directive({
selector: '[appInput]',
standalone: true,
})
export class AppInputDirective implements OnInit, OnChanges, OnDestroy {
@Input() showError = false;
@Input() errorTemplateRef: TemplateRef<unknown> | undefined;
private _errorElement: HTMLElement | undefined;
private _errorPlaceholderElement: HTMLElement | undefined;
private _errorSubscription: Subscription | undefined;
constructor(
private _el: ElementRef<HTMLInputElement>,
private _renderer: Renderer2,
private _ngControl: NgControl,
) {}
ngOnInit(): void {
// If there's a placeholder to display the error, use it;
// otherwise, create a div element below the input.
this._errorPlaceholderElement = <HTMLElement>this.errorTemplateRef?.elementRef.nativeElement;
const inputParent = <HTMLElement>this._renderer.parentNode(this._el.nativeElement);
// Create a div element for the error message.
this._errorElement = <HTMLElement>this._renderer.createElement('div');
this._renderer.addClass(this._errorElement, 'text-coral-red');
const wrapperElement = <HTMLElement>this._renderer.createElement('div');
if (!this._errorPlaceholderElement && inputParent) {
const wrapperClasses = ['flex', 'flex-col', 'gap-1'];
inputParent.classList.contains('w-full') && wrapperClasses.push('w-full');
inputParent.classList.contains('h-full') && wrapperClasses.push('h-full');
wrapperElement.classList.add(...wrapperClasses);
this._renderer.insertBefore(inputParent, wrapperElement, this._el.nativeElement);
this._renderer.appendChild(wrapperElement, this._el.nativeElement);
// Insert the error element after the target element.
this._renderer.insertBefore(inputParent, this._errorElement, this._el.nativeElement.nextSibling);
}
// If there's a placeholder, position the error in its place.
if (this._errorPlaceholderElement) {
// Replace the original element with the new one.
const parent = <HTMLElement>this._renderer.parentNode(this._errorPlaceholderElement);
this._renderer.insertBefore(parent, this._errorElement, this._errorPlaceholderElement);
this._renderer.removeChild(parent, this._errorPlaceholderElement);
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['showError']?.currentValue) {
this._errorSubscription = this._ngControl.statusChanges
?.pipe(startWith(1))
.subscribe(() => this._updateErrorDisplay());
} else {
this._errorSubscription?.unsubscribe();
}
}
ngOnDestroy(): void {
this._errorSubscription?.unsubscribe();
}
private _updateErrorDisplay(): void {
this._renderer.setProperty(this._errorElement, 'innerText', null);
if (this._ngControl.errors) {
const firstErrorKey = Object.keys(this._ngControl.errors)[0];
const errorValue = <{ [key: string]: unknown }>this._ngControl.errors[firstErrorKey];
const errorMessage = fillInPlaceholders(validationErrorString[firstErrorKey], errorValue);
if (errorMessage) {
this._renderer.setProperty(this._errorElement, 'innerText', errorMessage);
}
}
}
}
在这一刻,它用一个简单的代替了 ng-tamplate,但我想使用它
答: 暂无答案
评论