2015-10-05 56 views
6

我正在尝试整合d3和angular2 alpha.37(从here开始)。我目前遇到的问题是生成的DOM元素不能获得仿真样式视图封装中使用的属性,所以我无法设置它们的样式,而没有将该元素的视图封装设置为无(或本机,但我宁愿使用模拟)。添加主机属性到生成的DOM元素

我设法以编程提取的元件所需的属性分量[1]内,然后将其添加到所生成的元素[2],它不工作,但这显然难以置信哈克:

import {Component, View, Attribute, ElementRef, LifecycleEvent} from 'angular2/angular2'; 

import d3 from 'd3'; 

@Component({ 
    selector: 'bar-graph', 
    properties: [ 'data' ] 
}) 
@View({ 
    template: '<div class="chart"></div>', 
    styles: [`.chart { 
    background: #eee; 
    padding: 3px; 
    } 

    div.bar { 
    width: 0; 
    transition: all 1s ease-out; 
    -moz-transition: all 1s ease-out; 
    -webkit-transition: all 1s ease-out; 
    } 

    div.bar { 
    font: 10px sans-serif; 
    background-color: steelblue; 
    text-align: right; 
    padding: 3px; 
    margin: 5px; 
    color: white; 
    box-shadow: 2px 2px 2px #666; 
    }`] 
}) 
export class BarGraph implements LifecycleEvent.OnChanges { 
    data: Array<number>; 
    divs: any; 
    constructor(elementRef: ElementRef, @Attribute('width') width: string, @Attribute('height') height: string) { 


    var el:any = elementRef.nativeElement; 
    var graph:any = d3.select(el); 

    this.hostAttr = graph[0][0].children[0].attributes[1].name; //hack here [1] 

    this.divs = graph. 
     select('div.chart'). 
     style({ 
     'width': width + 'px', 
     'height': height + 'px', 
     }). 
     selectAll('div.bar'); 

    } 

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

    this.divs.data(newValue) 
     .enter().append('div') 
      .classed('bar', true) 
      .attr(this.hostAttr, true) //add the attribute here [2] 
      .style('width', d => d + '%') 
      .text(d => d + '%'); 

    } 

    onChanges() { 
    this.render(this.data); 
    } 

} 

是否有推荐的方式来处理这类事情(或者我应该停止修改Angular2之外的DOM)?

+1

如果您想要一个答案,您至少必须升级到beta.0。 –

+0

@EricMartinez在beta.7上有同样的问题。 –

回答

1

不是一个完整的答案(还),但也许一些有用的信息,可以找到一个解决方案帮助:

  • 问题仍然存在beta.8。将视图封装设置为None并使用全局样式是我可以开始工作的唯一解决方案。使用Native似乎没有任何元素被添加到DOM中,但我不得不做更多的测试来找出原因。
  • 由OP提出的黑客工程,可以重构成合理的解决方案,至少在我看来。
  • d3.js的特定情况下,当引入由库内部创建的元素时,事情变得更加棘手,例如,通过d3.svg命名空间中的方法。毫无疑问,可以找到解决方法。
  • 但我认为这个问题比d3大。有很多图书馆都有自己的DOM生成/操作机制,并且认为其中的一部分将在某些应用程序中集成到某个或其他应用程序中并不现实。从这个意义上说,这个问题似乎还没有出现(或者我的Google-fu本周特别弱)令人惊讶。

在解决方案方面,这些是我目前考虑的情况下,这两种方法没有一个人想出了更好的东西:

  1. 实施某种形式的后处理器,可引导部分DOM树并设置样式范围属性。也许作为一个指令?
  2. 尝试装饰渲染器,如暗示here