Angular 2组件 - 访问DOM(或创建没有模板的组件,纯粹来自JS)

Ana*_*oly 22 dom angular

试着在这里玩Angular 2 ......明白它仍处于alpha状态.

如何从Component访问DOM元素?具体来说,我想使用其他库如d3从代码生成自定义DOM.我想我需要创建一个组件并以某种方式插入组件生命周期来改变DOM与d3 ...任何想法从哪里开始挖掘?

我正在使用这个快速启动回购.

谢谢!

Har*_*yte 19

如果您不介意使用Directive而不是Component,那么它很简单.对于打字稿中的Angular 2.0.0-alpha.33,您可以使用D3通过注入ElementRef来操作DOM:

@Directive({
    selector:   'scatter-plot',
    lifecycle: [LifecycleEvent.onChange],
    properties: [ 'data' ]
})
export class ScatterPlot {

    root: Selection<any>;
    data: Array<ScatterPlotDataPoint>;

    x: (number) => number;
    y: (number) => number;

    defaultSize: string;
    circles: any;

    constructor(
        @Inject(ElementRef) elementRef: ElementRef,
        @Attribute('height') height: string,
        @Attribute('default-size') defaultSize: string
    ) {
        var el:HTMLElement = elementRef.nativeElement;
        this.root = d3.select(el);

        this.defaultSize = defaultSize ? defaultSize : "5";
        this.circles = this.root
            .append('svg')
            .attr('class', 'chart')
            .style({
                'width':  '100%',
                'height': height ? height + 'px': '',
            }).
            selectAll('circle');

    }

    render(newValue) {
        if (!newValue) return;

        this.x = d3.scale.linear().domain([-10, 110]).range([0, 250]);
        this.y = d3.scale.linear().domain([-10, 110]).range([100, 0]);

        this.circles = this.circles
            .data(newValue);

        this.circles.exit().remove();

        this.circles.enter()
            .append('circle');

        this.circles
            .transition()
            .attr("r", d => d.size ? d.size: this.defaultSize)
            .style("fill", d => d.color)
            .attr('cx', d => this.x(d.x))
            .attr('cy', d => this.y(d.y));

    }

    onChange() {
        this.render(this.data);
    }
}
Run Code Online (Sandbox Code Playgroud)


sup*_*ary 7

使用ElementRef

ElementRef会将当前DOM节点注入您的组件.ElementRef服务将始终是您当前DOM节点的本地服务.

注入后,您可以使用nativeElement获取实际的DOM节点:

var el = elementRef.nativeElement
Run Code Online (Sandbox Code Playgroud)

一旦你有了这个,你可以以任何你喜欢的方式操作它,使用DOM脚本,或使用像jQuery这样的DOM包装器:

$(el)
  .append('<p>Some interesting Stuff')
  .addClass('my_class');
Run Code Online (Sandbox Code Playgroud)

但如果你能提供帮助,不要这样做

请注意,与Angular 1一样,不鼓励使用直接DOM操作.你可以使用模板完成你所有的工作,你应该在大多数时候都喜欢这种工作方式.

直接DOM操作导致令人费解,难以理解,难以测试的代码.

有时候,它似乎是最好的解决方案.例如,如果您必须与第三方集成,那么高复杂性框架就像图形库一样.

这是一个有效的例子(在ES6中)

var AppComponent = ng.core
  .Component({
    selector: "app",
    template:
    `
      <div>Captured element</div>
    `
  })
  .Class({
    constructor: [ng.core.ElementRef, function(elementRef) {
      var el = elementRef.nativeElement
      el;
    }]
  })
Run Code Online (Sandbox Code Playgroud)


taz*_*taz 5

注意:[已弃用]

您可以使用"BrowserDomAdapter"
https://angular.io/docs/ts/latest/api/platform/browser/BrowserDomAdapter-class.html

import {BrowserDomAdapter} from 'angular2/platform/browser'

@Component({
  selector: 'dom',
  templateUrl: 'path/to/template.html',
  providers: [BrowserDomAdapter]
})
export class DomComponent {
  constructor(private _dom: BrowserDomAdapter) {
    var domIWant = this._dom.query('whatever you want to get');
  }
}
Run Code Online (Sandbox Code Playgroud)

处理

  1. 导入BrowserDomAdapter
  2. 申请提供者:[BrowserDomAdapter]
  3. 在构造函数中启动()
  4. 使用实例化BrowserDomAdapter获取dom

  • 在新版本中已弃用或未导出,因此最好使用elementRef (2认同)