我构建这些元素......
$(EmbedAssembliesIntoApk)
...来自以下数据:
<svg>
<g class="group">
<text class="label">Hello</text>
</g>
<g class="group">
<text class="label">World</text>
</g>
</svg>
创建后,我会更改数据并再次运行[
{ id: 'a', label: 'Hello' },
{ id: 'b', label: 'World' },
]
。但是文本不会更新。
代码https://jsfiddle.net/ginpei/r7b65fzt/:
.data()
第二次,它会查看绑定到function render (data, container) {
const group = container.selectAll('.group')
.data(data, d => d.id)
const entered = group.enter().append('g')
.attr({
class: 'group'
})
entered.append('text')
.attr({
class: 'label'
})
.attr({ y: (d, i) => 20 + i * 20})
const label = group.selectAll('.label')
.text(d => d.label)
}
的数据,但绑定到.group
的数据不会更新。我预计数据将会第一次设置。
如何更新它们?
实际上,如果我为子元素添加.label
,我发现它有效。
.data()
这是更新它们的正确方法吗?
以更简单的方式更新它们会很棒,因为我的实际代码有很多后代元素。
答案 0 :(得分:3)
此处的解决方案非常简单:只需将selectAll
更改为select
。
const label = group.select('.label')
.text(d => d.label);
要理解原因,这是我用select
和selectAll
之间的差异制作的表格:
+--------------------+----------------------------------+----------------------------+
| Method | select() | selectAll() |
+--------------------+----------------------------------+----------------------------+
| Selection | selects the first element | selects all elements that |
| | that matches the selector string | match the selector string |
+--------------------+----------------------------------+----------------------------+
| Grouping | Does not affect grouping | Affects grouping |
+--------------------+----------------------------------+----------------------------+
| Data propagation | Propagates data | Doesn't propagate data |
+--------------------+----------------------------------+----------------------------+
注意传播数据与传播数据。
以下是您的代码更改和setTimeout
更改数据:
// d3.js 3.x
const container = d3.select('body').append('svg')
function render(data, container) {
const group = container.selectAll('.group')
.data(data, d => d.id)
const entered = group.enter().append('g')
.attr({
class: 'group'
})
entered.append('text')
.attr({
class: 'label'
})
.attr({
y: (d, i) => 20 + i * 20
})
const label = group.select('.label')
.text(d => d.label);
}
// first try
const data1 = [{
id: 'a',
label: 'Hello'
}, {
id: 'b',
label: 'World'
}, ]
render(data1, container)
// update
const data2 = [{
id: 'a',
label: 'Goodbye'
}, {
id: 'b',
label: 'Universe'
}, ]
setTimeout(function() {
render(data2, container)
}, 1000)
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
PS:您的代码无法使用v4(或v5)。