我在D3代码中处理事件处理程序时遇到问题:在重构之前,它按预期工作:
choice_groups
.append("span")
.attr("class", "repeat-choice")
.text("Modifica questa scelta")
.on("click", repeat_choice);
调用了repeat_choice()函数,并单击了span.repeat-choice元素的索引i参数。
因为我只想将这个事件处理程序附加到具有多个嵌套数据元素的元素,所以我重构了上面的代码:
choice_groups
.each(function(d, i) {
if(d.length > 1) {
d3.select(this)
.append("span")
.attr("class", "repeat-choice")
.text("Modifica questa scelta")
.on("click", repeat_choice);
} else {
d3.select(this)
.append("span")
.attr("class", "no-choice")
.html(" ");
}
});
但是,现在总是在i = 0的情况下调用repeat_choice()处理程序函数,无论哪个是被点击的元素的索引。
我想我没有正确使用selection.each():得到的标记符合预期(和重构前一样),只有单击处理函数不会传递元素的索引。
答案 0 :(得分:2)
您的内部d3.select()正在创建一个新选择,因此每次都会重置i = 0(在该选择的上下文中)。您可以有条件地设置属性:
choice_groups
.append("span")
.attr("class", function(d,i) { return d.length > 1 ? "repeat-choice" : "no-choice"; })
.text(function(d,i) { return d.length > 1 ? "Modifica questa scelta" : null; });
或者可能只重新选择“repeat-choice”元素并稍后绑定点击处理:
choice_groups
.filter(function(d,i){ return d.length > 1;})
.on("click", repeat_choice);
(传递给repeat_choice的i也只计算第二个选择中的过滤元素,我认为)
希望有所帮助。