我想通过将
我已经有一个属性指令来限制输入字段的最大长度。我将其作为指令,因为这已应用于项目中不同文件之间的许多输入字段。但是现在的问题是,当用户超出限制时,我必须显示 mat-error 。我不想自己在所有文件的每个输入字段下添加
<mat-form-field floatLabel="auto">
<input [formControl]="displayNameControl"
mongoIndexLimit
[charLength]="charLength"
matInput
name="displayName"
placeholder="Stack Name"
autocomplete="off"
required />
</mat-form-field>
这是我的指令
import { Directive, OnInit, NgModule, ElementRef, OnChanges, Input, SimpleChanges, Renderer2 } from '@angular/core';
@Directive({
selector: '[mongoIndexLimit]'
})
export class MongoIndexLimitDirective implements OnInit, OnChanges {
@Input() public charLength?: number;
private maxLength = 5;
constructor(
private el: ElementRef<HTMLElement>,
private renderer: Renderer2
) { }
public ngOnInit() {
this.el.nativeElement.setAttribute('maxLength', this.maxLength.toString());
}
public ngOnChanges(changes: SimpleChanges) {
if (changes.charLength.currentValue >= 5) {
const child = document.createElement('mat-error');
this.renderer.appendChild(this.el.nativeElement.parentElement.parentElement.parentElement, child);
}
}
}
当我尝试上述操作时,我可以将
我希望结果是设置了maxLength的输入组件,并且动态生成的mat-error会显示超出限制的时间,就像下面的示例中一样。
https://material.angular.io/components/input/examples (标题为带有自定义错误状态匹配器的输入)
对不起,我的英语不好。
答案 0 :(得分:2)
当然,您可以在逻辑上添加一个垫错误。 NetBasal中有一个amazing article。
我在stackblitz中输入了一个简单的版本。在这次堆叠闪电战中,我将指令附加到mat-form-field并进行变通,以附加新组件mat-error-component。这使我可以使用CSS和动画。
关键是使用ViewContainerRef通过ComponentFactoryResolver动态添加组件
好,指令的代码:
export class MongoIndexLimitDirective implements AfterViewInit {
ref: ComponentRef<MatErrorComponent>;
constructor(
private vcr: ViewContainerRef,
private resolver: ComponentFactoryResolver,
private formField:MatFormField
) { }
public ngAfterViewInit()
{
this.formField._control.ngControl.statusChanges.subscribe(res=>this.onChange(res))
}
public onChange(res) {
if (this.formField._control.ngControl.invalid)
{
this.setError('error')
}
else
this.setError('')
}
setError(text: string) {
if (!this.ref) {
const factory = this.resolver.resolveComponentFactory(MatErrorComponent);
this.formField._elementRef
this.ref = this.vcr.createComponent(factory);
}
this.ref.instance.error=text;
}
MatErrorComponent(为方便起见,我称其为。要小心地将其放入主模块的entryComponents中)看起来比实际要复杂,这是因为“动画”,但本质上是<mat-error>{{message}}</mat-error>
@Component({
selector: 'custom-error',
template:`
<div [@animation]="_state" style="margin-top:-1rem;font-size:.75rem">
<mat-error >
{{message}}
</mat-error>
</div>
`,
animations: [
trigger('animation', [
state('show', style({
opacity: 1,
})),
state('hide', style({
opacity: 0,
transform: 'translateY(-1rem)'
})),
transition('show => hide', animate('200ms ease-out')),
transition('* => show', animate('200ms ease-in'))
]),
]
})
export class MatErrorComponent{
_error:any
_state:any
message;
@Input()
set error(value)
{
if (value && !this.message)
{
this.message=value;
this._state='hide'
setTimeout(()=>
{
this._state='show'
})
}
else{
this._error=value;
this._state=value?'show':'hide'
}
}
已更新是对mat-error-component更好的理解。
我们可以考虑差异错误,并像这样改善过渡
@Component({
selector: '[custom-error]',
template: `
<div [@animation]="increment" *ngIf="show" style="margin-top:-1rem;font-size:.75rem">
<mat-error >
{{message}}
</mat-error>
</div>
`,
animations: [
trigger('animation', [
transition(':increment', [
style({ opacity: 0}),
animate('200ms ease-in', style({ opacity: 1 })),
]),
transition(':enter', [
style({ opacity: 0, transform: 'translateY(-1rem)' }),
animate('200ms ease-in', style({ opacity: 1, transform: 'translateY(0)' })),
]),
transition(':leave', [
animate('200ms ease-out', style({ opacity: 0, transform: 'translateY(-1rem)' }))
])])
]
})
export class MatErrorComponent {
show: boolean
message: string;
increment:number=0;
@Input()
set error(value) {
if (value)
{
if (this.message!=value)
this.increment++;
this.message = value;
}
this.show = value ? true : false;
}
}
这是因为当消息错误更改时,会出现一个新的动画-在这种情况下,例如,将不透明度从0更改为1。在我们的指令中,将函数onChange更改为
public onChange(res) {
if (this.control.invalid)
{
if (this.control.errors.required)
this.setError(this.formField._control.placeholder+' required')
else
this.setError(this.formField._control.placeholder+' incorrect')
}
else
this.setError('')
}
答案 1 :(得分:0)
您不会动态添加Could not find symbol '&shuffle'
,只需将其放在此处即可。它严格与mat-error
合作,并且如果mat-form-field
处于matInput
状态,它将变为可见。
将其视为错误消息的容器。您所要做的就是调整消息(以防您可能有多个验证规则,并且想要为所有验证规则定制消息)。
Angular Material文档中的代码
invalid
答案 2 :(得分:0)
是的,您可以为matInput动态插入错误
<mat-form-field>
<mat-label>{{item.label}}</mat-label>
<input type="text" matInput [formControlName]="item.name">
<mat-error *ngIf="form.get(item.name).invalid">{{getErrorMessage(form.get(item.name))}}</mat-error>
</mat-form-field>