【问题标题】:How to dynamically increment variable names in javascript?如何在javascript中动态增加变量名?
【发布时间】:2020-02-05 21:59:58
【问题描述】:

我正在使用 Node/Express 构建一个简单的食谱应用程序。用户获得一个“新配方”HTML 表单,他们可以在其中单击“添加成分”按钮并根据需要向表单中添加任意数量的成分。使用 jQuery,每次单击加号图标时,都会为新成分生成一个新的文本输入:

        var newIngredient = $('#newIngredient').val();

        ingredientCount++;

        //give each ingredient a unique name based on count
        var ingredientID = "ingredient_" + ingredientCount

        // reset input to blank
        $("#newIngredient").val("");

        // add ingredient to list for user to see or edit.
        $("#ingredientsList").append(
           '<input class="form-control" type="text" required 
            name=' + ingredientID + ' value="' + newIngredient + '">')

添加的每种成分都通过计数器分配一个唯一的名称。这一切都很好,提交表单时我得到:

{
  name: 'Soup',
  ingredient_1: 'carrots',
  ingredient_2: 'salt',
  ingredient_3: 'turnips',
  method: 'Throw all these ingredients together and voila, you have a terrible soup.'
}

在后端,我想获取这些成分中的每一种并将它们添加到“成分”数组中(因为我认为我不能从 HTML 表单中发送一组成分)。我显然不想硬编码ingredients.push(req.body.ingredient_1)ingredients.push(req.body.ingredient_2) 等...因为每个食谱的成分数量会有所不同。 有没有办法增加变量名?这可能说明了我正在尝试做的事情,尽管我知道它显然不起作用:

ingredientsList=[];

var counter=1;

while(req.body.**"ingredient_"+counter**){
    ingredientsList.push(req.body.**'ingredient_'+counter**);
    counter++
}

欢迎将动态创建的名称:值对从 HTML 表单传递到 JS 后端的替代想法,但我也想知道是否有可能以我上面尝试过的方式动态增加参数 - req.body.parameter[i]

谢谢!

【问题讨论】:

  • 好像你在重新发明一个数组
  • 我只会将它们全部设为 name='ingredient',然后在后端获取一系列成分。

标签: javascript html node.js express


【解决方案1】:

您可以动态检查类似的键,只要您确定它们是数字即可。如果有可能有 ingredient_1ingredient_3没有成分_2,那么您需要删除 break 语句。

var data = {
  name: 'Soup',
  ingredient_1: 'carrots',
  ingredient_2: 'salt',
  ingredient_3: 'turnips',
  method: 'Throw all these ingredients together and voila, you have a terrible soup.'
}
var ingredientsList=[];
for(var num=1; num<10000;num++){
  if(!data['ingredient_'+num]){break;}
  ingredientsList.push(data['ingredient_'+num]);
}
console.log(ingredientsList);

【讨论】:

  • 如果您愿意,可以在一行中完成此操作:let ingredients = Object.keys(data).filter(k =&gt; k.startsWith("ingredient_")).map(o =&gt; data[o]);
【解决方案2】:

因为我认为我不能从 HTML 发送一系列成分 表格

那不是真的。我可以建议将 JSON 对象发送到服务器吗?

这样你就可以:

  1. 发送您想要的任何结构
  2. 通过将解析移至后端来简化您的工作

来自客户:

var data = {
    name: 'Soup',
    ingredient_1: 'carrots',
    ingredient_2: 'salt',
    ingredient_3: 'turnips',
    method: 'Throw all these ingredients together and voila, you have a terrible soup.'
};

$.ajax({
    url: url,
    type: 'POST',
    contentType: 'application/json',
    data: JSON.stringify(data),
    dataType: 'json',
    success: function(data) {
        //On success do something
        alert(data);
    },
    error: function(xhr, ajaxOptions, thrownError) {
        //On error do something
    }
});

...在服务器端类似:

const bodyParser = require('body-parser')

app.use(
  bodyParser.urlencoded({
    extended: true
  })
)

app.use(bodyParser.json())

app.post('/endpoint', (req, res) => {
  console.log(req.body.name) // 'Soup'
})

希望对你有帮助! ?

【讨论】:

  • 谢谢,这很有用,但我想我在服务器端仍然有同样的问题。如果我想选择所有成分,我将不得不手动指定 req.body.ingredient_1 + req.body.ingredient_2 ... 等,这不仅效率低下而且有问题,因为我的程序不知道已经提交了多少成分并且因此要尝试添加多少成分。这就是为什么我希望有某种方法可以选择所有以成分_开头的属性,或者每次都会附加数字的代码,从而允许我编写类似成分_{counter}之类的东西......
  • @bobby_belfast 没问题。我唯一想提的是——你可以像 for (var prop in obj) {if (Object.prototype.hasOwnProperty.call(obj, prop)) { //prop is property i.e. ingredient_1, 2,3 and obj[prop] its value}} 那样动态循环遍历 JavaScript 对象属性
【解决方案3】:

您可以使用字符串文字:

const ingredientsList = [];
var counter=1;
while(yourCondition){
    ingredientsList.push(`req.body.ingredient_${counter++}`);
}

【讨论】:

  • 这只是将“req.body.ingredient_1”添加到数组中。即['req.body.ingredient_1','req.body.ingredient_2]等
【解决方案4】:

编辑:您可以在一行中轻松完成此操作:

const DATA = {
  name: 'Soup',
  ingredient_1: 'carrots',
  ingredient_2: 'salt',
  ingredient_3: 'turnips',
  method: 'Throw all these ingredients together and voila, you have a terrible soup.'
}

let i = Object.keys(DATA).filter(k => k.startsWith("ing")).map(o => DATA[o]);

console.log(i);

不要将属性添加到您的对象中,如ingredient1ingredient2 等。为什么不直接使用一个名为ingredients 的数组?

这样的事情在一个非常高的层次上展示了如何实现你想要的。

var RECIPE = {
  name: "",
  ingredients: [],
  method: "",
}

$("#add-ingredient").on('click', event => {
  let ingredient = $("#ingredient").val();
  if (ingredient) {
    RECIPE.ingredients.push(ingredient);
    $("#ingredient-list").append(`<li>${ingredient}</li>`);
    $("#ingredient").val("");
  } else {
    alert("Please enter ingredient first");
  }
});

$("#submit").on('click', event => {
  let name = $("#recipe-name").val();
  let method = $("#recipe-method").val();
  let empties = [];
  if (name) { RECIPE.name = name; } 
  else { empties.push("recipe name"); }
  if (method) { RECIPE.method = method; } 
  else { empties.push("recipe method"); }
  if (RECIPE.ingredients.length <= 0) { empties.push("ingredients"); }
  if (empties.length) { alert(`Please fill out ${empties.join(" and ")}`); } 
  else { alert("This is what we would post:\r\n\r\n" + JSON.stringify(RECIPE,null,2)); }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="recipe-name" type="text" placeholder="Enter Recipe Name"/>
<br />
<textarea id="recipe-method" placeholder="Enter Recipe Method"></textarea>
<br />
<input id="ingredient" type="text" placeholder="Enter Ingredient" />
<button id="add-ingredient">Add Ingredient</button>
<ul id="ingredient-list"></ul>
<br /><hr />
<button id="submit">Submit Recipe</button>

【讨论】:

    猜你喜欢
    • 2012-10-02
    • 1970-01-01
    • 2013-10-24
    • 2017-06-30
    • 2011-05-12
    • 1970-01-01
    • 2011-09-30
    • 2011-07-04
    • 2019-12-23
    相关资源
    最近更新 更多