Angular如何正确编写*ngIf条件 复用ng-template错误提示模板
问题解答
你预想的在*ngIf中判断上下文来源的写法不可行,核心问题有两点:
*ngTemplateOutlet的context参数只接受普通对象,你直接传入*object* | keyvalue的转换结果不符合语法,Angular不会自动在模板内执行遍历逻辑。- 模板作用域内没有内置变量可以标识当前传入的上下文对应哪个源对象,强行写
context === *object*既没有可访问的变量承接判断,还会让公共模板和组件内的具体变量强耦合,完全失去复用的意义。
正确实现方案
不要在公共模板里判断数据源来源,把可变的部分(错误提示内容)作为上下文参数传入模板,固定的遍历、错误类型判断逻辑全部收敛到公共模板中即可。
推荐写法:传入错误文案映射
首先在组件类中为每个校验对象定义对应的错误提示文案映射:
// 组件TS文件 // 每个字段对应的错误提示 readonly fieldErrorMap = { username: { required: '请输入用户名', pattern: '用户名仅支持字母、数字组合', maxlength: '用户名长度不能超过16位' }, password: { required: '请输入密码', pattern: '密码需包含大小写字母和数字', maxlength: '密码长度不能超过20位' }, phone: { required: '请输入手机号', pattern: '请输入正确的11位手机号', maxlength: '手机号长度不能超过11位' } }
模板部分实现:
<!-- 复用公共错误模板,传入当前字段的错误对象和对应文案 --> <ng-container *ngTemplateOutlet="errorTpl; context: { errorList: usernameErrors | keyvalue, messages: fieldErrorMap.username }"></ng-container> <ng-container *ngTemplateOutlet="errorTpl; context: { errorList: passwordErrors | keyvalue, messages: fieldErrorMap.password }"></ng-container> <ng-container *ngTemplateOutlet="errorTpl; context: { errorList: phoneErrors | keyvalue, messages: fieldErrorMap.phone }"></ng-container> <!-- 公共错误提示模板 --> <ng-template #errorTpl let-errorList="errorList" let-messages="messages"> <ng-container *ngFor="let error of errorList"> <p class="error-message"> <span *ngIf="error.key === 'required'">{{ messages.required }}</span> <span *ngIf="error.key === 'pattern'">{{ messages.pattern }}</span> <span *ngIf="error.key === 'maxlength'">{{ messages.maxlength }}</span> </p> </ng-container> </ng-template>
这种写法下公共模板和具体业务字段完全解耦,后续新增校验字段、新增错误类型只需要扩展对应的文案映射即可,不需要修改公共模板逻辑。
复杂场景:传入自定义内容模板
如果错误提示包含自定义HTML结构、交互逻辑,可以把可变的提示内容作为模板片段传入:
<!-- 调用公共模板时传入对应错误的自定义模板 --> <ng-container *ngTemplateOutlet="errorTpl; context: { errorList: usernameErrors | keyvalue, requiredTpl: usernameRequired, patternTpl: usernamePattern, maxlengthTpl: usernameMax }"></ng-container> <!-- 用户名字段自定义错误提示 --> <ng-template #usernameRequired><strong>必填:</strong>请输入你的登录用户名</ng-template> <ng-template #usernamePattern><strong>格式错误:</strong>用户名不能包含特殊字符</ng-template> <ng-template #usernameMax><strong>超长:</strong>用户名最多16个字符</ng-template> <!-- 公共模板 --> <ng-template #errorTpl let-errorList="errorList" let-requiredTpl="requiredTpl" let-patternTpl="patternTpl" let-maxlengthTpl="maxlengthTpl"> <ng-container *ngFor="let error of errorList"> <p class="error-message"> <span *ngIf="error.key === 'required'"><ng-container *ngTemplateOutlet="requiredTpl"></ng-container></span> <span *ngIf="error.key === 'pattern'"><ng-container *ngTemplateOutlet="patternTpl"></ng-container></span> <span *ngIf="error.key === 'maxlength'"><ng-container *ngTemplateOutlet="maxlengthTpl"></ng-container></span> </p> </ng-container> </ng-template>
内容的提问来源于stack exchange,提问作者Ekaterina
相关产品推荐
相关产品推荐

