Angular中ng-template绑定*ngIf方法失效问题求助
问题:*ngIf绑定方法返回值不生效
我写了一个方法isApplicantMinor(),想用它的返回值控制下方HTML内容的显示,但完全不生效,*ngIf好像被忽略了。
HTML代码:
<div class="field"> <label for="birthday">Birthday</label> <mat-form-field class="example-full-width"> <mat-label>Choose a date</mat-label> <input matInput [matDatepicker]="picker" id="birthday" [formControl]="birthdayFormControl" (dateInput)="calculateAge()" (dateChange)="calculateAge()"> <mat-hint>MM/DD/YYYY</mat-hint> <mat-datepicker-toggle matIconSuffix [for]="picker"> </mat-datepicker-toggle> <mat-datepicker #picker></mat-datepicker> </mat-form-field> </div> </div> <ng-template *ngIf="isApplicantMinor()"> <!-- 不生效 --> <div class="row"> <div class="column"> <div class="field"> <label for="parentBirthday">Birthday</label> <mat-form-field class="example-full-width"> <mat-label>Choose a date</mat-label> <input matInput [matDatepicker]="picker" id="parentBirthday"> <mat-hint>MM/DD/YYYY</mat-hint> <mat-datepicker-toggle matIconSuffix [for]="picker"> <!-- <mat-icon matDatepickerToggleIcon>keyboard_arrow_down</mat-icon> --> </mat-datepicker-toggle> <mat-datepicker #picker></mat-datepicker> </mat-form-field> </div> </div> <div class="column"> <div class="field"> <label for="birthday">Parent's Email Address</label> <mat-form-field class="example-full-width"> <mat-label>Email</mat-label> <input type="email" matInput [formControl]="emailFormControl" [errorStateMatcher]="matcher" placeholder="Ex. pat@example.com"> <mat-hint>Enter your parents email!</mat-hint> <mat-error *ngIf="emailFormControl.hasError('email') && !emailFormControl.hasError('required')"> Please enter a valid email address </mat-error> <mat-error *ngIf="emailFormControl.hasError('required')"> Email is <strong>required</strong> </mat-error> </mat-form-field> </div> </div> </div> </ng-template>
TypeScript代码:
isApplicantMinor(): boolean { this.applicantIsMinor = false; if (this.applicantAge < 18) { this.applicantIsMinor = true; } return this.applicantIsMinor; } calculateAge() { // 日期格式为字符串"22/10/1988" // debugger; this.applicantIsMinor = false; var dateString = moment(this.birthdayFormControl.value).format("MM/DD/YYYY") || moment(new Date().toDateString()).format("MM/DD/YYYY"); let age: number = 0; if (dateString === undefined || dateString?.length === 0) { dateString = new Date().toDateString(); } var dateParts = dateString.split("/"); var dateObject = new Date(+dateParts[2], +dateParts[0], +dateParts[1]); console.log(dateObject); if (dateString) { var timeDiff = Math.abs(Date.now() - new Date(dateObject).getTime()); age = Math.floor(timeDiff / (1000 * 3600 * 24) / 365.25); console.log(age); } this.applicantAge = age; if (this.applicantAge < 18) { this.applicantIsMinor = true; } return age; }
解决方案
1. ng-template 不能直接用 *ngIf
*ngIf 是结构型指令,底层会把当前元素转换成 ng-template 再添加渲染逻辑。你手动写了 <ng-template> 后直接加 *ngIf 会导致逻辑冲突,推荐两种修正方式:
- 方案A:移除
ng-template,把*ngIf绑定到内容根div
<!-- 替换原ng-template部分 --> <div class="row" *ngIf="isApplicantMinor()"> <!-- 内部内容保持不变 --> </div>
- 方案B:保留
ng-template,用ngTemplateOutlet配合条件
<ng-template #minorSection> <div class="row"> <!-- 内部内容保持不变 --> </div> </ng-template> <ng-container *ngIf="isApplicantMinor()" *ngTemplateOutlet="minorSection"></ng-container>
2. isApplicantMinor() 方法逻辑冗余且错误
每次调用方法时你先重置 this.applicantIsMinor 为 false,会覆盖 calculateAge() 中已经计算好的正确值。直接返回已维护的变量即可:
isApplicantMinor(): boolean { // 移除不必要的重置操作,直接返回计算后的结果 return this.applicantIsMinor; }
3. 模板引用变量冲突
两个日期选择器都用了 #picker,会导致模板引用混乱,修改第二个日期选择器的变量名:
<!-- 父生日日期选择器部分 --> <input matInput [matDatepicker]="parentPicker" id="parentBirthday"> <!-- ... --> <mat-datepicker-toggle matIconSuffix [for]="parentPicker"> </mat-datepicker-toggle> <mat-datepicker #parentPicker></mat-datepicker>
4. 日期计算的月份偏移问题
JavaScript 的 Date 构造函数中月份是从 0 开始的(0=1月,11=12月),你直接用 dateParts[0](MM格式的月份)会导致日期解析错误,比如10月会被识别为11月,修正如下:
// 原代码 var dateObject = new Date(+dateParts[2], +dateParts[0], +dateParts[1]); // 修改后 var dateObject = new Date(+dateParts[2], +dateParts[0] - 1, +dateParts[1]);
内容的提问来源于stack exchange,提问作者GettingStarted
相关产品推荐
相关产品推荐

