2015-10-05 23 views
6

Tôi đang cố tích hợp d3 và angular2 alpha.37 (bắt đầu từ here). Vấn đề tôi hiện đang gặp là các phần tử DOM được tạo không nhận các thuộc tính được sử dụng trong gói đóng gói kiểu dáng được mô phỏng và vì vậy tôi không thể tạo kiểu cho chúng mà không đặt đóng gói khung nhìn cho thành phần thành Không (hoặc Gốc, nhưng tôi thay vì sử dụng mô phỏng).Thêm thuộc tính máy chủ vào các phần tử DOM được tạo

tôi quản lý để lập trình trích xuất các thuộc tính cần thiết từ một yếu tố bên trong phần [1], và sau đó thêm nó vào các yếu tố tạo ra [2], mà không làm việc, nhưng điều này rõ ràng là vô cùng 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); 
    } 

} 

Có cách nào được khuyến nghị để xử lý loại điều này (hoặc tôi nên dừng tinkering với DOM bên ngoài Angular2)?

+1

Nếu bạn muốn có câu trả lời, ít nhất bạn cũng sẽ phải nâng cấp lên beta.0. –

+0

@EricMartinez Cùng một vấn đề trên phiên bản beta.7. –

Trả lời

1

Không phải là một câu trả lời đầy đủ (chưa), nhưng có thể một số thông tin hữu ích có thể giúp trong việc tìm kiếm một giải pháp:

  • Vấn đề này vẫn còn tồn tại trong beta.8. Đặt chế độ xem đóng gói thành None và sử dụng kiểu toàn cầu là giải pháp duy nhất tôi có thể làm việc. Sử dụng Native dường như không dẫn đến kết quả là không có phần tử nào được thêm vào DOM, nhưng tôi phải thực hiện thêm một số thử nghiệm để tìm ra nguyên nhân.
  • Bản hack do OP đề xuất và có thể được tái cấu trúc thành giải pháp hợp lý, ít nhất theo ý kiến ​​của tôi.
  • Trong trường hợp cụ thể là d3.js, mọi thứ trở nên phức tạp hơn khi giới thiệu các yếu tố được tạo trong thư viện, ví dụ: thông qua các phương thức trong không gian tên d3.svg. Chắc chắn một cách giải quyết cho rằng có thể được tìm thấy là tốt.
  • Tôi tin rằng vấn đề lớn hơn d3. Có rất nhiều thư viện ở đó có các cơ chế tạo/thao tác DOM riêng của họ, và không phải là không thực tế khi nghĩ rằng một phần của các thư viện đó sẽ được tích hợp trong một số ứng dụng angular2 nào đó. Theo nghĩa đó, thật đáng ngạc nhiên là vấn đề này dường như chưa xuất hiện (hoặc có lẽ Google-fu của tôi đặc biệt yếu trong tuần này).

Về giải pháp, đây là hai cách tiếp cận mà tôi hiện đang xem xét trong trường hợp không có ai đi lên với một cái gì đó đẹp hơn:

  1. Thực hiện một số loại sau xử lý mà đi một DOM phần cây và đặt thuộc tính phạm vi kiểu. Có lẽ như một chỉ thị?
  2. Cố gắng trang trí cho trình kết xuất, như được gợi ý here.
Các vấn đề liên quan