繁体   English   中英

迭代 HTMLcollection 以在构造函数中动态定义值?

[英]Iterate over an HTMLcollection to dynamically define values in a constructor function?

我会直接看描述和示例代码,因为我敢打赌你们中的许多人和我一样对标题感到困惑(尽我所能)。

情况:我有一个表单,它使用构造函数将输入数据提交给对象的新实例。

当前代码:

// Selectors
var submit = document.getElementById('submit-btn');
var formValues = document.getElementsByClassName('input');

// ** Task Object
function Task(arrayOfValues) {
  this.title = arrayOfValues[0].value;
  this.deadline = arrayOfValues[1].value;
  this.status = arrayOfValues[2].value;
}
submit.addEventListener('click', function(e) {
  e.preventDefault();
  var newTask = new Task(formValues);  
}, false);

问题:将数组作为参数传递并手动分配每个索引对我来说感觉非常脆弱。 如果我要扩展表单的数据收集,我将不得不手动将每个新值分配为一个单独的变量。 如果要迭代数组并在构造函数中为变量动态赋值,则语法或模式是什么? 先感谢您。 非常感谢任何和所有帮助。

所需代码示例

var formValues = document.getElementsByClassName('input');

// ** Task Object
function Task(arrayOfValues) {
  this.values = arrayOfValues;

  for (var i=0;i<this.values.length;i++) {
    var key = this.values[i].getAttribute('name'); 
    // This should be used with "this" to reference key ie. "this.title, this.deadline, this.status ect...

    var value = this.values[i].value;
    // This will be the value associated with each key reference ie. "this"

    return this[key] = value;
    // is this even possible ?        
  }

}
submit.addEventListener('click', function(e) {
  e.preventDefault();
  var newTask = new Task(formValues);  
}, false);

我就分别取三个参数,让调用者弄清楚哪一个是标题、截止日期或状态

function Task(title, deadline, status) {
  this.title = title;
  this.deadline = deadline;
  this.status = status;
}

现在您的呼叫者可以通过使用 ID、数据属性或他们想要的任何东西来确定哪个是哪个。

<input id="title-x"> <input id="deadline"> <input id="status">

submit.addEventListener('click', function(e) {
  e.preventDefault();
  var getVal = function(id) { return  document.getElementById(id).value; }
  var newTask = new Task(getVal('title-x'), getVal('deadline'), getVal('status'));  
}, false);

现在您的构造函数不依赖于数组中的顺序,甚至不依赖于它们是 DOM 元素。

你总是可以有一个合同,其中一个特定的输入通过数据属性映射到一个任务字段

<input data-task-field="title">
<input data-task-field="deadline">
<input data-task-field="status">
<input data-task-field="newField">

/**
 * @param {object} taskDescription 
 * @param {string} taskDescription.title
 * @param {string} taskDescription.deadline
 * @param {string} taskDescription.status
 * @param {string} taskDescription.newField
 */
function Task(taskDescription) {
  this.task = taskDescription;
}

submit.addEventListener('click', function(e) {
  e.preventDefault();
  var tasks = document.querySelectorAll('input[data-task-field]');
  var taskSpec = {};
  for (var i=0; i < tasks.length; i++) {
    taskSpec[tasks.getAttribute('data-task-field')] = tasks.value; 
  }
  var newTask = new Task(taskSpec);  
}, false);

只需使用表单元素的名称作为对象中的属性名称。

function Task(arrayOfValues) {
  for (var i=0;i<arrayOfValues.length;i++) {
    var key = arrayOfValues[i].name;
    var value = arrayOfValues[i].value;
    this[key] = value;       
  }
}

不要在循环内使用return ,这将在处理数组中的第一个元素后结束构造函数,并忽略其余部分。

我会使用关联数组 -

http://www.w3schools.com/js/js_arrays.asp

var assArray = [];
assArray["title"] = document.getElementbyID(......)

这使您的数组在语义上有意义且不那么脆弱。 如果您扩展表单并不重要,只要您不更改名称,它就会继续工作。

这也意味着您不必在每次展开表单时更改构造函数的调用签名,您只需更改主体以处理数组中的新元素(或不更改,根据您的选择)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM