将D3.js与Angular 2一起使用

Zia*_*han 75 d3.js angular

我已成功将Angular 2(Alpha 44)与D3.js集成:

<html>
<head>
<title>Angular 2 QuickStart</title>
<script src="../node_modules/systemjs/dist/system.src.js"></script>
<script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<script>
  System.config({packages: {'app': {defaultExtension: 'js'}}});
  System.import('app/app');
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

app.js:

/// <reference path="./../../typings/tsd.d.ts" />

import {Component, bootstrap, ElementRef} from 'angular2/angular2';

@Component({
  selector: 'my-app',
  template: '<h1>D3.js Integrated if background is yellow</h1>',
  providers: [ElementRef]
})
class AppComponent { 
  elementRef: ElementRef;

  constructor(elementRef: ElementRef) {
   this.elementRef = elementRef;
  }

afterViewInit(){
    console.log("afterViewInit() called");
    d3.select(this.elementRef.nativeElement).select("h1").style("background-color", "yellow");
  }
}
bootstrap(AppComponent);
Run Code Online (Sandbox Code Playgroud)

一切都很好.但是ElementRef的Angular 2文档说明如下:

当需要直接访问DOM时,请使用此API作为最后的手段.请使用Angular提供的模板和数据绑定.或者,您可以查看{@link Renderer},它提供了可以安全使用的API,即使不支持直接访问本机元素也是如此.依赖于直接DOM访问会在应用程序和渲染层之间产生紧密耦合,这使得无法将两者分开并将应用程序部署到Web工作者中.

现在问题是如何将D3.js与Renderer API集成?

Eri*_*nez 55

要使用Renderer,您需要原始HTML元素(aka nativeElement).所以基本上你必须使用你的库,获取原始元素并将其传递给Renderer.

例如

// h3[0][0] contains the raw element
var h3 = d3.select(this.el.nativeElement).select('h3');
this.renderer.setElementStyle(h3[0][0], 'background-color', 'blue');
Run Code Online (Sandbox Code Playgroud)

关于ElementRef的警告是关于直接使用它.这意味着这是不鼓励的

elementRef.nativeElement.style.backgroundColor = 'blue';
Run Code Online (Sandbox Code Playgroud)

但这很好

renderer.setElementStyle(elementRef.nativeElement, 'background-color', 'blue');
Run Code Online (Sandbox Code Playgroud)

出于显示目的,您也可以使用它与jQuery

// h2[0] contains the raw element
var h2 = jQuery(this.el.nativeElement).find('h2');
this.renderer.setElementStyle(h2[0], 'background-color', 'blue');
Run Code Online (Sandbox Code Playgroud)

我的建议是坚持使用angular2为您提供的方便,而不依赖于其他库.

使用纯angular2,您有两种简单的方法

  • 使用指令
// This directive would style all the H3 elements inside MyComp
@Directive({
    selector : 'h3',
    host : {
        '[style.background-color]' : "'blue'"
    }
})
class H3 {}

@Component({
    selector : 'my-comp',
    template : '<h3>some text</h3>',
    directives : [H3]
})
class MyComp {}
Run Code Online (Sandbox Code Playgroud)
  • 将ViewChild与局部变量一起使用
@Component({
    selector : 'my-comp',
    template : '<h3 #myH3>some text</h3>',
})
class MyComp {
    @ViewChild('myH3') myH3;
    ngAfterViewInit() {
        this.renderer.setElementStyle(this.myH3.nativeElement, 'background-color', 'blue');
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我在这个答案中提到的所有案例的plnkr.当然,您的要求可能会有所不同,但尽可能尝试使用angular2.

  • 那么,对于使用bootstrap的collapse插件的例子,我是否正确地说'jQuery(this.el.nativeElement).collapse('show');`将是一个完全可以接受的实例化插件的方式? (2认同)

Pia*_*M4n 5

试试这个:

npm install d3@3.5.36 --save 设置所需的版本

npm install @types/d3@3.5.36 --save 或者更高版本,如果你想要d3 4+

然后在你的ts待办事项

import * as d3 from 'd3';

应该工作得很好