如何从 Angular 2 的指令中附加动态 DOM 元素?

Posted

技术标签:

【中文标题】如何从 Angular 2 的指令中附加动态 DOM 元素?【英文标题】:How to append dynamic DOM elements from a directive in Angular 2? 【发布时间】:2017-12-18 12:40:00 【问题描述】:

我有一个附加元素的 Angular 1.x 指令。简而言之:

app.directive('mydirective', function() 
  template: '<ng-transclude></ng-transclude>',
  link: function(el) 
    var child = angular.element("<div/>");
    el.append(child);
  

我可以像这样将该指令迁移到 Angular 2:

@Directive(
  selector: '[mydirective']
)
export class MyDirective implements OnInit 
  constructor(private elementRef: ElementRef)  

  ngOnit() 
    var child = angular.element("<div/>");
    this.elementRef.nativeElement.append(child);
  

困扰我的是nativeElement官方文档中的这句话:

当需要直接访问 DOM 时,将此 API 用作最后一个资源。

我的问题是 - 我怎样才能正确地将这个指令迁移到 Angular 2?我唯一的要求是动态构建一个元素并将其附加到带有指令的元素中。

【问题讨论】:

【参考方案1】:

使用Angular提供的Renderer来操作DOM:

import  DOCUMENT  from '@angular/common';

export class MyDirective implements OnInit 
  constructor(
    private elementRef: ElementRef,
    private renderer: Renderer2,
    @Inject(DOCUMENT) private document: Document)  

  ngOnInit() 
    const child = this.document.createElement('div');
    this.renderer.appendChild(this.elementRef.nativeElement, child);
  

这不依赖于像 appendChild() 这样的原生 DOM API,因此在某种程度上它是一种独立于平台的方法。

【讨论】:

创建一个属性指令向DOM添加/删除元素是不是错了?我们不应该创建结构指令吗?我也在上面创建了一个question @DRB,是的,您应该使用结构指令。我在文章Working with DOM in Angular: unexpected consequences and optimization techniques中描述了这种方法 @Inject(DOCUMENT) private document 完成了什么? 以独立于平台的方式注入document,具体取决于平台如何定义document 这是Working with DOM in Angular: unexpected consequences and optimization techniques的固定链接。

以上是关于如何从 Angular 2 的指令中附加动态 DOM 元素?的主要内容,如果未能解决你的问题,请参考以下文章

访问附加到组件选择器的 angular 2 指令

如何使用 Angular 6 中的自定义指令来呈现动态生成的内联 SVG

Angular 4 - 在 jquery append 中编译 [ngClass]

Angular 2 的异步加载路由数据和构建路由指令

Angular 2:向动态创建的组件添加指令

在标签文本中附加星号的 Angular 指令