嵌套选择与更新 [英] Nested selection with Update

查看:42
本文介绍了嵌套选择与更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为嵌套选择构建了我认为是最新的解决方案使用更新模式.

I've built what I think is the most current solution for a nested selection with an update pattern.

但是,每次单击更新时,我总是得到外部选择,而不总是得到内部(嵌套)选择.控制台日志显示了一个正确形成的数组数组.

However, each time update is clicked, I always get the outer selection, but not always the inner (nested) selection. The log to console show a correctly formed array of arrays.

这是v5中嵌套选择的正确设置吗?这是一个Codepen

Is this the correct setup for a nested selection in v5? Here's a codepen

<!doctype html>
<html>

<head>
  <meta charset="UTF-8">
  <title>#</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <style type="text/css">
    .outer {
      border: 1px solid black;
      background-color: grey;
      width: 100%;
      height: 100px;
      position: relative;
      display: flex;
    }
    
    .inner {
      display: flex;
      justify-content: flex-start;
      border: 1px solid blue;
      background-color: cyan;
      width: 50px;
      height: 50px;
      position: relative;
    }
  </style>

</head>

<body>
  <button id='update'>update</button>
  <div id="anchor"></div>
  <script>
    const updateButton = document.getElementById('update');
    const anchor = d3.select('#anchor');

    updateButton.addEventListener('click', function() {
      update(
        Array.from({
          length: Math.ceil(Math.random() * 5)
        }, function() {
          return Array.from({
            length: Math.ceil(Math.random() * 5)
          }, function() {
            return Math.ceil(Math.random() * 5);
          });
        })
      );
    });


    function update(data) {

      const outer = anchor.selectAll('.outer').data(data);

      outer.exit().remove();

      outer.enter()
        .append('div')
        .merge(outer)
        .attr("class", "outer");

      const inner = outer.selectAll('.inner').data(function(d) {
        return d;
      });

      inner.exit().remove();

      inner.enter()
        .append('div')
        .merge(inner)
        .attr("class", "inner")
        .text(function(d) {
          return d;
        });
    }
  </script>
</body>

</html>

推荐答案

在这种情况下,您必须重新分配更新选择,因此其引用将与enter选择合并(此处为'm为 let 更改了 const ,以便重新分配选择):

In a case like this one you have to reassign the update selection, so its reference is merged with the enter selection (here I'm changing const for let in order to reassign the selection):

//here is the update selection:
let outer = anchor.selectAll('.outer').data(data);

//here is the enter selection:
const outerEnter = outer.enter()
    .append('div')
    .attr("class", "outer");

//reassigning here: 
outer = outerEnter.merge(outer);

否则,即使您在enter选择中链接了 merge 方法, other 也仅是更新选择.如果您使用 outer.size().

Otherwise other will be only the update selection, even if you have a merge method chained in the enter selection. You can clearly see this if you console outer.size().

这是您所做的更改的代码:

Here is your code with that change:

const updateButton = document.getElementById('update');
const anchor = d3.select('#anchor');

updateButton.addEventListener('click', function() {
  update(
    Array.from({
      length: Math.ceil(Math.random() * 5)
    }, function() {
      return Array.from({
        length: Math.ceil(Math.random() * 5)
      }, function() {
        return Math.ceil(Math.random() * 5);
      });
    })
  );
});


function update(data) {
  let outer = anchor.selectAll('.outer').data(data);

  outer.exit().remove();

  const outerEnter = outer.enter()
    .append('div')
    .attr("class", "outer");

  outer = outerEnter.merge(outer);

  const inner = outer.selectAll('.inner').data(function(d) {
    return d;
  });

  inner.exit().remove();

  inner.enter()
    .append('div')
    .attr("class", "inner")
    .merge(inner)
    .text(function(d) {
      return d;
    });
}

	.outer {
		border: 1px solid black;
		background-color: grey;
		width: 100%;
		height: 100px;
		position: relative;
		display: flex;
	}
	.inner {
		display: flex;
		justify-content: flex-start;
		border: 1px solid blue;
		background-color: cyan;
		width: 50px;
		height: 50px;
		position: relative;
	}

<script src="https://d3js.org/d3.v5.min.js"></script>
<button id='update'>update</button>
<div id="anchor"></div>

这篇关于嵌套选择与更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆