22

ここで Angular 2 を試してみましたが、まだアルファ版であることがわかりました。

Component から DOM 要素にアクセスするにはどうすればよいですか? 具体的には、 d3などの他のライブラリを使用して、コードからカスタム DOM を生成したいと考えています。コンポーネントを作成し、何らかの方法でコンポーネントのライフサークルにプラグインしてDOMをd3で変更する必要があると思います...どこから掘り始めればよいでしょうか?

このクイックスタート リポジトリを使用しています。

ありがとう!

4

5 に答える 5

19

Component の代わりに Directive を使用してもかまわない場合は、簡単です。typescript の Angular 2.0.0-alpha.33 の場合、ElementRef を注入することで D3 を使用して 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);
    }
}
于 2015-08-18T01:12:36.947 に答える
7

ElementRef を使用

ElementRef は、現在の DOM ノードをコンポーネントに挿入します。ElementRef サービスは、常に現在の DOM ノードに対してローカルになります。

注入すると、nativeElement を使用して実際の DOM ノードを取得できます。

var el = elementRef.nativeElement

これを取得したら、DOM スクリプトを使用するか、jQuery のような DOM ラッパーを使用して、好きな方法で操作できます。

$(el)
  .append('<p>Some interesting Stuff')
  .addClass('my_class');

しかし、あなたがそれを助けることができるなら、これをしないでください

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;
    }]
  })
于 2016-02-27T18:15:17.680 に答える
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');
  }
}

プロセス

  1. BrowserDomAdapter のインポート
  2. プロバイダーの適用: [BrowserDomAdapter]
  3. constructor() で開始する
  4. インスタンス化された BrowserDomAdapter を使用して dom を取得する
于 2016-01-25T08:58:47.377 に答える