从数据集值更新多级对象值

时间:2017-09-25 11:01:34

标签: javascript

很难解释。

var options = {
  container: node,
  pin: {
    size: [50, 50],
    anchor: 0,
    animation: 0
  }
}

让我们以上面的对象为例。我想循环遍历HTMLElement中的数据集,并使用数据集值更新上述值。这消除了手动检查数据集值是否存在的需要,然后替换该值。

到目前为止我得到了什么:

(function() {
  for( const data in node.dataset ) {
    // First remove the 'map' as this isn't required, then split any values with multiple capitals,
    // as these corrospond to multilevel object values. 
    var key = (data.replace("map", "")).split(/(?=[A-Z])/), value = node.dataset[data];

    const findOption = function() {

    };

    // Check that there is a value
    if (value !== null) {
      const opt = null;
      // Find the corresponding default option

    }
  }
}.call(_));

这是带有数据集属性的HTML,这应该有助于一切更有意义:

<div data-map data-map-offset='[10, 10]' data-map-pin-size='[20, 20]'></div>

正如您在上面所看到的,属性data-map-pin-size需要替换对象中的值,但我不确定如何引用该对象,因为通常我会options.pin.size或{{1 }}。但由于这个循环不知道它需要走多远,我不能总是依赖于此,我需要某种回调函数吗?这就是为什么我开始options['pin']['size']然而我不太确定从哪里开始!

修改 这是我到目前为止所做的,但是这不是更新findOption()对象,它只是设置options的值。

opt

2 个答案:

答案 0 :(得分:1)

如果您将options转换为此格式:

var options = {
  container: node,
  pinSize: [50, 50],
  pinAnchor: 0,
  pinAnimation: 0
}

您的实施可以简化为:

for (const key in node.dataset) {
  const opt = key.replace(/^map(.)/, (match, c) => c.toLowerCase())
  options[opt] = JSON.parse(node.dataset[key])
}

假设您打算在HTML data-属性中使用符合JSON的值。

答案 1 :(得分:1)

在这里,我添加了recursive function来通过查找options对象上的特定键来设置值。您可以看到,对于任何长度的data set属性,值都已正确设置。

这适用于任何类型的options object格式动态

我还添加了一个额外的样本来演示

(function() {


  //A function to set the value on a nested object by
  //recursively finding the key
  function setValue(object, key, value) {
    var value;
    Object.keys(object).some(function(k) {
      if (k === key) {
        object[k] = value;
      }
      if (object[k] && typeof object[k] === 'object') {
        setValue(object[k], key, value);
      }
    });
  }

  node = document.getElementById("elem");

  var options = {
    container: node,
    pin: {
      size: [50, 50],
      anchor: 0,
      animation: 0,
      value: {
        xy: [1, 1]
      }
    }
  }

  for (const data in node.dataset) {
    // First remove the 'map' as this isn't required, then split any values with multiple capitals,
    // as these corrospond to multilevel object values. 
    var keys = (data.replace("map", "")).split(/(?=[A-Z])/),
      value = node.dataset[data];

    var findOption = function() {
      keys.forEach(function(key, index) {
        if (index == keys.length - 1) {
          setValue(options, key.toLowerCase(), value);
        }
      })
    }();


    // Check that there is a value
    if (value !== null) {
      const opt = null;
      // Find the corresponding default option
    }
  }

  console.log(options);

}.call());
<div data-map data-map-offset='[10, 10]' data-map-pin-size='[20, 20]' data-map-pin-value-xy='[0, 5]' id="elem"></div>