首页 > 解决方案 > ngIf with validation controls

问题描述

I'm writing a custom form component which is basically a textbox that will change to a label or a textarea depending on a specific property.

So if the custom component is set as read-only, the textbox should be hidden and a label must be displayed.

This hide and show logic work flawlessly. However, the dom element responsible for displaying validation messages throws an error when the control is not found.

<span class="form-control-readonly" *ngIf="readonly == true" #valuelabel>
 {{inputModel}}
</span>

<input 
    *ngIf="readonly != true" 
    #control="ngModel" 
    [id]="id" 
    type="text" 
    class="form-control" 
    [placeholder]="caption" 
    [(ngModel)]="inputModel" 
    (ngModelChange)="onTextChange()" 
    [maxlength]="maxLength"
    [required]="isRequired === true ? '' : null"  
    [ngClass]="{'invalid': !control.valid, 'valid': control.valid }"> 

 <div *ngIf="(readonly == false) && (control.invalid && hideFeedback === false)" class="invalid-feedback">
     <div *ngIf="(readonly == false) && (control.errors.required)">{{ caption }} is required</div>
     <div *ngIf="(readonly == false) && (control.errors.maxlength)">{{ caption }} should be {{ control.errors.maxlength.requiredLength }} characters long </div>        
 </div>

control.errors in the last div throws "Cannot read property 'invalid' of undefined" error. Probably, because the control doesn't exist in dom.

When ngIf on input is changed to hidden, it begins to work, but I want to achieve it with ngIf.

标签: angularform-control

解决方案


不要将ngIf放在输入上,而是将输入和验证 div 包装在另一个 div 中并应用条件。因此,对于以下条件,输入模型将始终可见。

<span class="form-control-readonly" *ngIf="readonly == true" #valuelabel>
 {{inputModel}}
</span>

<div *ngIf="readonly != true">
    <input 
        #control="ngModel" 
        [id]="id" 
        type="text" 
        class="form-control" 
        [placeholder]="caption" 
        [(ngModel)]="inputModel" 
        (ngModelChange)="onTextChange()" 
        [maxlength]="maxLength"
        [required]="isRequired === true ? '' : null"  
        [ngClass]="{'invalid': !control.valid, 'valid': control.valid }"> 

    <div *ngIf="(readonly == false) && (control.invalid && hideFeedback===false)" class="invalid-feedback">
        <div *ngIf="(readonly == false) && (control.errors.required)">{{ caption }} is required</div>
        <div *ngIf="(readonly == false) && (control.errors.maxlength)">{{ caption }} should be {{ control.errors.maxlength.requiredLength }} characters long </div>        
    </div>
</div>

推荐阅读