首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的d3数据中的第一个元素没有更新?

为什么我的d3数据中的第一个元素没有更新?
EN

Stack Overflow用户
提问于 2019-11-20 13:07:25
回答 1查看 25关注 0票数 0

因此,我目前正在使用此代码来呈现元素列表,并(希望)指定活动元素,当其中一个元素被单击时,该元素可以更改。

代码语言:javascript
复制
let active_experiment_id = null;

function set_experiments() {
    const u = d3.select('#experiments')
          .selectAll('li')
          .data(Object.values(experiments).sort((a, b) => {
              const a_time = moment(a['created']),
                    b_time = moment(b['created']);
              if (a_time.isBefore(b_time))
                  return 1;
              else if (a_time.isAfter(b_time))
                  return -1;
              else
                  return 0;
          }), (d) => d);

    const entering = u.enter()
          .append('li')
          .classed('nav-item', true)
          .classed('active', (d) => d.active_experiment)
          .on('click', d => {
              if (d.experiment_id !== active_experiment_id)
                  set_active_experiment(d.experiment_id);
          })
          .append('a')
          .classed('nav-link', true)
          .classed('active', (d) => d.active_experiment)
          .append('p')
          .text((d) => { return d.name; });

    u.exit().remove();
}

function set_active_experiment(experiment_id) {
    if (experiment_id === null) {
        active_experiment_id = null;
        set_classes(null);
        set_workflows(null);
        set_tasks(null);
        set_seleced_task(null, null);
        return;
    }
    if (active_experiment_id !== null)
        experiments[active_experiment_id].active_experiment = false;
    active_experiment_id = experiment_id;
    experiments[active_experiment_id].active_experiment = true;

    fetch_tasks(experiment_id)
        .then(() => {
            set_experiments();
            set_classes(experiment_id);
            set_workflows(experiment_id);
            set_tasks(experiment_id);
            set_selected_task(experiment_id, experiments[experiment_id].root_task_id);
        });
}

我目前在列表中有两个数据元素,我可以单击第二个数据元素并获得要应用的active类。但是,我不能让第一个被点击。我尝试了调试,但在第一个任务(下面的experiment_id=2)上甚至没有调用enter函数。这些元素如下所示:

代码语言:javascript
复制
experiments = {1: {
  experiment_id: 1,
  name: "Experiment One",
  created: (before 2)
  ...
}, 2: {
  experiment_id: 2,
  name: "Experiment Two",
  created: (after 1),
  ...
}
EN

回答 1

Stack Overflow用户

发布于 2019-11-20 23:08:22

我相信我已经弄明白了问题所在。因为我使用的是Object.values,所以只有第二个实验保持了它的位置。在此之后,由于数据是通过引用直接绑定的(使用键(d) => d),因此d3会将元素本身作为键测试进行比较。因此,无论您选择哪种键方法,d3仍然会将对象的键与其自身进行比较,而不会注册该对象是否已更新。因此,为了解决这个问题,我每次都会创建一个数据的投影副本,并使用一个新的键方法来减少通过enterexit的对象数量。

代码语言:javascript
复制
function set_experiments() {
    const key = d => `${d.experiment_id}${d.active_experiment}`;

    const data = Object.values(experiments).sort((a, b) => {
        const a_time = moment(a['created']),
              b_time = moment(b['created']);
        if (a_time.isBefore(b_time))
            return 1;
        else if (a_time.isAfter(b_time))
            return -1;
        else
            return 0;
    })
          .map(d => ({
              "experiment_id": d.experiment_id,
              "created": d.created,
              "name": d.name,
              "active_experiment": d.active_experiment,
          }));

    const u = d3.select('#experiments')
          .selectAll('li')
          .data(data, key);

    const entering = u.enter()
          .append('li')
          .classed('nav-item', true)
          .classed('active', (d) => {
              num_entered++;
              return d.active_experiment;
          })
          .on('click', d => {
              if (d.experiment_id !== active_experiment_id) {
                  set_active_experiment(d.experiment_id);
              }
          })
          .append('a')
          .classed('nav-link', true)
          .classed('active', (d) => {
              return d.active_experiment;
          })
          .append('p')
          .text((d) => { return d.name; });

    u.exit().remove();
}

虽然它不是最有效的,因为我仍然必须复制所有数据,但复制的数据不会影响DOM。只有更新值才是,因为新的键方法删除了多余的添加和删除。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58947074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档