如何创建可组合多模板的Angular自定义指令?
Angular自定义指令模板替换问题
需求说明
我需要创建一个自定义指令,实现从JSON/TS对象中读取HTML文本模板,将其中的<AD_GROUPS>自定义标签替换为开发者传入的模板并渲染到页面。
示例配置内容:
{ //... text: '<p>Many of our tools ...AD Groups:</p><AD_GROUPS id="AD_GROUPS"></AD_GROUPS><p>To request access, ...', AD_GROUPS: [ 'my-team-users' ], //... }
指令使用方式
<div *appAdGroupText="cfg"> <mat-list> <mat-list-item *ngFor="let group of cfg.AD_GROUPS">{{group}}</mat-list-item> </mat-list> </div>
已编写的指令代码
@Directive({selector: '[appAdGroupText]'}) export class AdGroupTextDirective implements OnChanges { _config: ConfigurationItemModel | undefined; constructor( private templateRef: TemplateRef<unknown>, private vcr: ViewContainerRef, private renderer: Renderer2 // private resolver: ComponentFactoryResolver ) { } @Input() set appAdGroupText(cfg: ConfigurationItemModel) { this._config = cfg; this.render(); } render() { const cfg = this._config; // config is set in a set method. This has the correct value const groupListDivElement: HTMLDivElement = this.renderer.createElement('my-group-text'); // creates a 'parent' element groupListDivElement.innerHTML = cfg.text; // set the inner html to the config text const adListDivRef = this.templateRef.createEmbeddedView(null); // create an unattached version of the template // loop through, and replace the "AD_GROUPS" custom tag with the generated template groupListDivElement.childNodes.forEach(n => { if (n.nodeName === 'AD_GROUPS') { n.replaceWith(adListDivRef.rootNodes[0]); // this is incorrect. I only get the root node, rather than the entire node with its children } // arguably, the above could be replaced with an Array.from(...) find / replace console.log(groupListDivElement); // SEE HTML OUTPUT // How do I render groupListDivElement in the VCR / renderer??? // this works will put the mat-list ONLYin: // let view = this.templateRef.createEmbeddedView(null); // this.vcr.insert(view); } }
当前控制台输出的HTML
<my-group-text _ngcontent-hwh-c107=""> <p>Many of our tools are restricted to specific groups in Active Directory. In order to access the required tools, you will need access to the following AD Groups:</p> <div _ngcontent-hwh-c107=""> <mat-list _ngcontent-hwh-c107="" class="mat-list mat-list-base"> <!--container--> </mat-list> </div> <p> To request access, <a href="https://access" target="_blank" rel="noopener noreferrer">click here</a> and fill out the form with the following information: <ad_form_table></ad_form_table> </p> <p>You will need to create a ticket for each of the above groups listed.</p> </ad-group-text>
待解决的问题
- 如何将
adListDivRef附加到正确的父元素中?我尝试过用this.renderer.parentNode(this.vcr.element.nativeElement)获取父元素,但不确定后续如何正确挂载。 mat-list中的*ngFor没有生成对应的列表项,怀疑是指令执行顺序问题导致后续指令未被触发,该如何解决?
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

