Setter函数,用于动态访问作为属性的数组中的字段

时间:2016-02-01 09:37:51

标签: javascript

我有一个表示物理模型的javascript模块,它的数据在数据对象中提供。此模块导出setter函数以设置数据对象的属性(注意: export 在下面的示例中删除)

这在顶级层次结构上非常有效,但如何在属性中设置特定值,例如数组属性的特定字段?

var modeldata = {
  current: 100,
  pipeline: [150,200,210,220]
}

set = (variable, val) => {
  if (modeldata[variable] == undefined) {
    console.log('modeldata['+variable+'] is not defined');
  } else {
    if (modeldata[variable] == val) {
      console.log('no change necessary');
    } else {
      var old = modeldata[variable];
      modeldata[variable] = val;
      console.log('changing modeldata['+variable+']: ' + old + ' to ' + modeldata[variable])
    }
  }
}

set('curren', 100);   // modeldata[curren] is not defined, OK
set('current', 100);  // no change necessary, OK
set('current', 120);  // changing modeldata[current]: 100 to 120, OK
set('pipeline[0]', 42); // modeldata[pipeline[0]] is not defined, FAIL

如何改变set函数问题modeldata['pipeline'][0] = 42;,但仍允许设置current属性,因为它现在有效?

我可以简单地为每个属性创建一个特定的setter,但我有> 100个属性和属性数量不固定。

另外,我可以调用set('pipeline', ...)并简单地覆盖整个数组,包括新数据。但如上所述,我想在不知道或触及其他所有内容的情况下仅更改数组的特定字段。

更新:我正在寻找一种解决方案,modeldata仅在set - 函数内访问且没有get - 函数可用。因此,setmodeldata的唯一界面。

5 个答案:

答案 0 :(得分:1)

这是对set函数的编辑,以便允许更改数组和子属性:

set = (variable, val) => variable.split('.').reduce((prev, curr, i, arr) => {
  if (i === arr.length - 1) {
    if (prev[curr] == undefined) {
      console.log('modeldata[' + variable + '] is not defined');
    } else {
      if (prev[curr] == val) {
        console.log('no change necessary');
      } else {
        var old = prev[curr];
        prev[curr] = val;
        console.log('changing modeldata[' + variable + ']: ' + old + ' to ' + prev[curr]);
        return prev[curr];
      }
    }
  } else {
    return prev[curr];
  }
}, modeldata)

你将

set('curren', 100); // modeldata[curren] is not defined, OK
set('current', 100); // no change necessary, OK
set('current', 120); // changing modeldata[current]: 100 to 120, OK
set('pipeline.0', 42); // changing modeldata[pipeline.0]: 150 to 42, OK

答案 1 :(得分:0)

我在set函数的最开头添加了这段代码,创建了一个快速而又脏的解决方法:

set = (variable, val) => {
  if (variable.indexOf('[')>0 && variable.indexOf(']')>0) {
    var old = eval('modeldata.'+variable);
    eval('modeldata.'+variable+'='+val);
    console.log('changing modeldata.'+variable+': ' + old + ' to ' + val)
    return;
  }

它有效,但使用eval()并不能让我感觉良好。我很想看到更好的答案。

答案 2 :(得分:0)

您可以参考以下代码:

    var getBothIndexVariables = function (input) {
        var openingIndex = input.indexOf('[');
        var secondVal = "";
        var indexVariable;
        if (openingIndex != -1) {
            secondVal = input.substring(openingIndex + 1, input.length - 1);

            indexVariable = {
                firstIndexVariable: input.substring(0,openingIndex),
                secondIndexVariable: secondVal,
            }
        }
        return indexVariable;
    }
    var modeldata = {
        current: 100,
        pipeline: [150, 200, 210, 220]
    }

    set = (variable, val) => {
        var tempVariable = getBothIndexVariables(variable);
        if (tempVariable) {
            debugger;
            var value = modeldata[tempVariable.firstIndexVariable][tempVariable.secondIndexVariable];
            modeldata[tempVariable.firstIndexVariable][tempVariable.secondIndexVariable] = val;
            console.log(value);
            return;
        }
        if (modeldata[variable] == undefined) {
            console.log('modeldata[' + variable + '] is not defined');
        } else {
            if (modeldata[variable] == val) {
                console.log('no change necessary');
            } else {
                var old = modeldata[variable];
                modeldata[variable] = val;
                console.log('changing modeldata[' + variable + ']: ' + old + ' to ' + modeldata[variable])
            }
        }
    }

    set('curren', 100);   // modeldata[curren] is not defined, OK
    set('current', 100);  // no change necessary, OK
    set('current', 120);  // changing modeldata[current]: 100 to 120, OK
    set('pipeline[0]', 42); // modeldata[pipeline[0]] is not defined, FAIL

答案 3 :(得分:0)

此条件modeldata检查set对象中是否存在不同的命名属性 扩展var modeldata = { current: 100, pipeline: [150,200,210,220] } var set = (variable, val, array_key) => { var prop = (typeof array_key == "number")? modeldata[variable][array_key] : modeldata[variable]; if (prop == undefined) { console.log('modeldata['+variable+'] is not defined'); } else { if (prop == val) { console.log('no change necessary'); } else { var old = prop; if (typeof array_key == "number"){ modeldata[variable][array_key] = val; } else { modeldata[variable] = val; } console.log('changing modeldata['+variable+']: ' + old + ' to ' + modeldata[variable]) } } }; set('curren', 100); // modeldata[curren] is not defined, OK set('current', 100); // no change necessary, OK set('current', 120); // changing modeldata[current]: 100 to 120, OK set('pipeline', 42, 0); // m console.log(modeldata); // the output: Object {current: 120, pipeline: Array[4]} ..... current: 120 pipeline: Array[4] 0: 42 1: 200 2: 210 3: 220 length: 4 函数,以便它可以考虑数组键:

{{1}}

答案 4 :(得分:0)

走这条路。



var result = this.articles.AsEnumerable().Where(r => {
        var res = r.Field<String>("ArticleVariations");
        if (res != null) return res.Equals(artNo);
        else return false;
    });
&#13;
&#13;
&#13;