提问者:小点点

handsontable getValue()函数表达式问题中的HOT-in-HOT动态handsontable


我正在尝试使用Handsontable版本0.34.4CE/1.14.2 PRO创建一个Handsontable in Handsontable(HOT-in-HOT)。有了这里的文档,一切都正常工作了...但是我想使用多个多维数组动态地创建它。

问题是,当您正常创建Handontable时,您可以很好地分配所有变量,而当您动态地执行此操作时,它也可以工作。当您在Handontable中引入自定义函数时,动态创建它们并不像通常那样简单。

正如您在下面的代码中看到的,我意识到我需要将getValue()函数作为一个表达式来传递,这样它才能工作。问题是表达式是动态创建的,因此函数中的变量不是在函数的局部范围内完成的,而是试图在函数运行时被访问。我需要将变量保存/设置/分配给函数中的变量,并尝试在表达式创建后被调用。

文档中HOT中的正常HOT。。。

  var
    carData = getCarData(),
    container = document.getElementById('example1'),
    manufacturerData,
    colors,
    color,
    colorData = [],
    hot;

  manufacturerData = [
    {name: 'BMW', country: 'Germany', owner: 'Bayerische Motoren Werke AG'},
    {name: 'Chrysler', country: 'USA', owner: 'Chrysler Group LLC'},
    {name: 'Nissan', country: 'Japan', owner: 'Nissan Motor Company Ltd'},
    {name: 'Suzuki', country: 'Japan', owner: 'Suzuki Motor Corporation'},
    {name: 'Toyota', country: 'Japan', owner: 'Toyota Motor Corporation'},
    {name: 'Volvo', country: 'Sweden', owner: 'Zhejiang Geely Holding Group'}
  ];
  colors = ['yellow', 'red', 'orange', 'green', 'blue', 'gray', 'black', 'white'];

  while (color = colors.shift()) {
    colorData.push([
      [color]
    ]);
  }

  hot = new Handsontable(container, {
    data: carData,
    colHeaders: ['Car', 'Year', 'Chassis color', 'Bumper color'],
    columns: [
      {
    type: 'handsontable',
    handsontable: {
      colHeaders: ['Marque', 'Country', 'Parent company'],
      autoColumnSize: true,
      data: manufacturerData,
      getValue: function() {
        var selection = this.getSelected();

        // Get always manufacture name of clicked row
        return this.getSourceDataAtRow(selection[0]).name;
      },
    }
      },
      {type: 'numeric'},
      {
    type: 'handsontable',
    handsontable: {
      colHeaders: false,
      data: colorData
    }
      },
      {
    type: 'handsontable',
    handsontable: {
      colHeaders: false,
      data: colorData
    }
      }
    ]
  });

我尝试动态执行的HOT-in-HOT设置…

if(data_arr[0][key][2]['cell_type'] == "handsontable" && data_table_1_col_headers_options_arr[key][0] != "NA")
{
    data_table_1_columns_arr[count]['handsontable'] = new Array();

    data_table_1_columns_arr[count]['handsontable']['colHeaders'] = data_arr[3][key][1][0];
    data_table_1_columns_arr[count]['handsontable']['autoColumnSize'] = true;
    data_table_1_columns_arr[count]['handsontable']['data'] = data_arr[3][key][0];

    //// THE ISSUE IS IN THE EXPRESSION BELOW. ////
    var temp_field_value_to_use = data_arr[3][key][1][1];
    var hot_in_hot_function = function ()
                {
                    var selection = this.getSelected();
                    var field_use = temp_field_value_to_use;
                    return this.getSourceDataAtRow(selection[0])[field_use];
                };

    data_table_1_columns_arr[count]['handsontable']['getValue'] = hot_in_hot_function;
}

正如您在上面的动态版本中所看到的,Handsontable是由多个多维数组定义的,本期只显示了其中的相关代码。其他地方有更多的代码用于配置表的其余部分。这个特定部分以单元格类型的条件开始。如果单元格类型id为Handsontable,则创建热中热中的单元格选项。请注意,这个动态创建构建了一个父Handsontable,它有多个使用不同HOT-in-HOT的列。问题出在注释下面的代码的表达式版本中。变量' temp_field_value_to_use '是我希望用于父Handsontable中的值的HOT-in-HOT中列的索引。由于该值/列索引基于父Handsontable中具有HOT-in-HOT的列而变化,因此变量必须动态保存到表达式中。现在,当代码全部运行时,变量“temp_field_value_to_use”总是给出最后一个赋值,这意味着它不是与表达式一起动态保存的,而是对每个HOT-in-HOT使用相同的函数/表达式。


共1个答案

匿名用户

我认为既然表达式是动态创建的,那么问题就在于表达式是如何创建的以及它的范围是如何设置的。经过一番研究,我找到了解决办法。该解决方案使用所谓的JavaScript闭包,这是一个自调用函数。请补充,或者尽可能做得更好,我希望这一路上能帮助到一些人。我也要求Handsontable添加他们的文档。

您可以在下面的代码中看到,外部函数被分配了动态变量,因此作用域发生了变化,因此内部函数使用了oter变量,而不是动态Handcontainable选项配置循环作用域中的变量。

if(data_arr[0][key][2]['cell_type'] == "handsontable" && data_table_1_col_headers_options_arr[key][0] != "NA")
{
    data_table_1_columns_arr[count]['handsontable'] = new Array();

    data_table_1_columns_arr[count]['handsontable']['colHeaders'] = data_arr[3][key][1][0];
    data_table_1_columns_arr[count]['handsontable']['autoColumnSize'] = true;
    data_table_1_columns_arr[count]['handsontable']['data'] = data_arr[3][key][0];

    var temp_field_value_to_use = data_arr[3][key][1][1];
    //// JavaScript Closure expression below. ////
    var hot_in_hot_function = (function ()
    {
        var field_use = temp_field_value_to_use;
        return function ()
        {
            var selection = this.getSelected();
            return this.getSourceDataAtRow(selection[0])[field_use];
        }
    })();

    data_table_1_columns_arr[count]['handsontable']['getValue'] = hot_in_hot_function;
}