2015-10-01 24 views
14

Có thể không? Tôi không chắc chắn, kể từ d3 sử dụng nặng nề của this rebindings và điều này dường như xung đột với ES6 spec.Sử dụng các chức năng mũi tên với d3

Ví dụ, sau đây hoạt động tốt:

// Working fine 
var data = [1,2,3] 
var svg = d3.select('body').append('svg').attr('height', 500).attr('width', 500).style('background-color', 'orange'); 
var gs = svg.selectAll('g').data(data).enter(); 
gs.append('circle') 
    .attr('cx', function() { return Math.random()*500; }) 
    .attr('cy', function() { return Math.random()*500; }) 
    .attr('r', function() { return Math.random()*100; }) 
    .each(function() { console.log(this); }); // this is bound to the current element in the enter selection 

Trong khi đây không làm việc như mong đợi (this không gắn kết với các yếu tố hiện tại trong nhập lựa chọn nhưng để Window đối tượng):

var data = [1,2,3] 
var svg = d3.select('body').append('svg').attr('height', 500).attr('width', 500).style('background-color', 'blue'); 
var gs = svg.selectAll('g').data(data).enter(); 
gs.append('circle') 
    .attr('cx',() => Math.random()*500) 
    .attr('cy',() => Math.random()*500) 
    .attr('r',() => Math.random()*100) 
    .each(() => console.log(this)); // this is bound to Window object 

Fiddle liên quan here.

+1

@chriskelly ví dụ của bạn chỉ đơn giản là đặt giá trị tương tự cho tất cả các yếu tố trong việc lựa chọn, đó không phải là những gì tôi muốn đạt được (đó là lý do tại sao các hàm được sử dụng trong cơ sở mỗi phần tử) – jarandaf

+1

Khi tôi chạy ví dụ của bạn, sự khác biệt duy nhất tôi thấy là nhật ký bảng điều khiển đầu ra. Nhưng tại sao bạn muốn truy cập '' 'this'''. Đây là một câu hỏi thú vị nhưng tôi muốn biết một trường hợp nó sẽ là một vấn đề. – chriskelly

+0

@chriskelly đó là một trường hợp sử dụng khá cụ thể (có một số hàm mà tôi muốn sử dụng lại để tạo ra một cấu trúc phức tạp của các phần tử trong nhóm svg, tôi cần 'this' để biết nhóm nào tôi đang tham chiếu đến, nơi các phần tử mới sẽ được thêm vào). – jarandaf

Trả lời

8

Bạn có thể sử dụng các chức năng mũi tên nếu bạn không cần truy cập vào this của phần tử hiện tại.

Dự phòng về các chức năng kiểu cũ cho các trường hợp bạn muốn truy cập this của phần tử hiện tại.

Hoặc sử dụng rõ ràng ràng buộc để cho phép chức năng của bạn (không mũi tên chức năng) để truy cập bất cứ đối tượng bạn muốn sử dụng .bind()

Để tránh làm việc với this bạn có tùy chọn sử dụng tên d3 hoặc lớp selectors để truy cập thuận tiện bất kỳ yếu tố nào. ví dụ:

var stuffINeed = svg.selectAll('.someClass'); 
2

Không thể sửa đổi hành vi của chức năng mũi tên. Ràng buộc của chúng là 'hardcoded' và không thể thay đổi bằng cách liên kết lại với phương thức bind hoặc bằng cách gọi bất kỳ phương thức Function nào khác chấp nhận ngữ cảnh thực thi rõ ràng (ví dụ: apply). Điều tương tự có thể nói về bất kỳ hàm ràng buộc nào - một khi bị ràng buộc, hàm trả về bị ràng buộc mãi mãi.

Có thể không?

Với trên trong tâm trí, nếu d3 sử dụng bind ing để cung cấp hành vi chaining thuận tiện, này không thể đạt được sử dụng chức năng mũi tên cho đến khi API d3 được sửa đổi trong một số cách để thích ứng với chúng.

5

Nếu bạn đang sử dụng d3v4, bạn có thể truy cập vào các nút DOM hiện tại như thế này:

gs.append('circle') 
    .attr('cx',() => Math.random()*500) 
    .attr('cy',() => Math.random()*500) 
    .attr('r',() => Math.random()*100) 
    .each((d, i, j) => console.log(j[i])); 
     // j is current group, i is current index 
Các vấn đề liên quan