如何在Angular的app-form-field组件中获取投影内容上的autoCompletion指令
问题描述
我有一个form-field组件,内部通过ng-content投影传入input HTML元素,我在该input元素上挂载了名为autoCompletion的指令,使用示例如下:
<app-form-field> <input [id]="autoCompleteSearchInput" [formControl]='search' type="text" autoComplete="off" class='input-underline search-bar idented-text' placeholder="Enter" autoCompletion #custom="autoCompletion"/> </app-form-field>
app-form-field组件的模板代码如下:
<form> <p>form-field works!</p> <ng-content></ng-content> </form>
我需要访问input上挂载的autoCompletion指令实例,目前的实现方式是给指令定义模板引用变量#custom="autoCompletion",然后在form-field组件中通过@ContentChild获取该实例,代码如下:
@ContentChild('custom') directive?: ElementRef; ngAfterContentInit() { console.log(this.directive); }
该方案存在的问题是模板引用名是硬编码的custom,我需要实现可自定义的引用名:当父组件中使用#someOtherName="autoCompletion"这类任意名称的模板引用时,app-form-field也能自动获取到该指令的引用。请问我该如何实现?
解决方案
你不需要依赖模板引用变量名来查询指令,直接将@ContentChild的查询参数设置为autoCompletion指令的类本身即可,完全和用户自定义的模板引用解耦。
具体实现步骤
- 在
app-form-field组件中导入你的AutoCompletion指令类 - 修改
@ContentChild的查询条件为指令类,代码如下:
import { Component, ContentChild, AfterContentInit } from '@angular/core'; // 替换为你实际的指令导入路径 import { AutoCompletion } from './auto-completion.directive'; @Component({ selector: 'app-form-field', templateUrl: './form-field.component.html', styleUrls: ['./form-field.component.css'] }) export class FormFieldComponent implements AfterContentInit { // 直接用指令类作为查询条件,自动匹配所有投影内容中挂载了该指令的元素 @ContentChild(AutoCompletion) autoCompletionIns?: AutoCompletion; ngAfterContentInit() { // 这里直接拿到指令实例,不受模板引用名影响 console.log(this.autoCompletionIns); } }
补充说明
- 这种写法不需要用户在使用时额外定义模板引用,就算用户完全不写
#xxx="autoCompletion"也能正常查询到指令实例 - 如果存在多个投影元素挂载了
autoCompletion指令,可以改用@ContentChildren(AutoCompletion)获取所有指令实例的QueryList - 你之前的代码中将返回值类型定义为
ElementRef是错误的,直接按指令类声明类型,拿到的就是指令本身的实例,如果需要获取指令关联的DOM元素,可以在AutoCompletion指令的构造函数中注入ElementRef后对外暴露即可。
内容的提问来源于stack exchange,提问作者peco123
相关产品推荐
相关产品推荐

