2015-10-05 5 views
6

Ich versuche, d3 und angular2 alpha.37 zu integrieren (gestartet von here). Das Problem, das ich momentan habe, ist, dass die generierten DOM-Elemente nicht die Attribute erhalten, die in der emulierten Verkapselung der Stilansicht verwendet werden. Daher kann ich sie nicht stylen, ohne die Verkapselung der Ansicht für das Element auf None (oder Native) zu setzen würde eher emuliert verwenden).Host-Attribut zu generierten DOM-Elementen hinzufügen

konnte ich das gewünschte Attribut aus einem Element in der Komponente programmatisch extrahieren [1], und dann auf die erzeugten Elemente hinzufügen [2], die Arbeit macht, aber das ist eindeutig unglaublich Hacky:

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); 
    } 

} 

Gibt es einen empfohlenen Weg, mit dieser Art von Dingen umzugehen (oder sollte ich aufhören, mit dem DOM außerhalb von Angular2 zu basteln)?

+1

Wenn Sie eine Antwort wollen, müssen Sie mindestens auf Beta.0 mindestens aktualisieren. –

+0

@EricMartinez Das gleiche Problem auf beta.7. –

Antwort

1

keine vollständige Antwort (noch) nicht, aber vielleicht einige nützliche Informationen, die bei der Suche nach einer Lösung helfen kann:

  • Das Problem besteht nach wie vor in beta.8. Das Festlegen der Ansichtseinkapselung auf None und das Verwenden globaler Stile war die einzige Lösung, die ich zur Arbeit bringen konnte. Die Verwendung von Native schien dazu zu führen, dass dem DOM überhaupt keine Elemente hinzugefügt wurden, aber ich musste noch einige Tests durchführen, um die Ursache herauszufinden.
  • Der von OP vorgeschlagene Hack funktioniert und könnte zumindest meiner Meinung nach zu einer vernünftigen Lösung umgestaltet werden.
  • Im speziellen Fall von wird es noch schwieriger, wenn Elemente eingeführt werden, die intern von der Bibliothek erstellt werden, z. durch die Methoden im Namespace d3.svg. Zweifellos könnte auch ein Workaround dafür gefunden werden.
  • Ich glaube, dass das Problem größer ist als d3 jedoch. Es gibt viele Bibliotheken da draußen, die ihre eigenen DOM-Erzeugungs-/Manipulationsmechanismen haben, und es ist nicht unrealistisch zu denken, dass ein Teil davon irgendwann in die eine oder andere Anwendung integriert sein wird. In diesem Sinne ist es überraschend, dass das Problem noch nicht aufgetaucht ist (oder vielleicht ist mein Google-Fu diese Woche besonders schwach).

in Lösungen, das sind die beiden Ansätze, die ich zur Zeit bei Berücksichtigung bin niemand kommt mit etwas schöner:

  1. irgendeine Art von Post-Prozessor implementieren, die eine teilweise DOM Wanderungen Baum und legt die Attribute des Stilbereichs fest. Vielleicht als Richtlinie?
  2. Versuchen Sie, den Renderer zu dekorieren, wie angedeutet here.