2016-05-03 3 views
1

Я получу право на описание и пример кода, поскольку, как я полагаю, многие из вас так же путаются в названии, как и я (старались изо всех сил).Итерации над HTMLcollection для динамического определения значений в функции конструктора?

Ситуация: У меня есть форма, которая отправляет входные данные в новый экземпляр объекта, используя функцию-конструктор.

ТОК КОД:

// 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); 
+0

Извините, но ваш пример плотно соединяет задачу с DOM, я думаю, что я предложил лучше разделить проблемы. –

ответ

1

Просто используйте имена элементов формы как имена свойств в объекте.

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 внутри цикла, который завершится конструктор после обработки первого элемента в массиве, и игнорировать все остальное.

+0

Спасибо, это было именно то, что я искал. Цените редактирование и ответ! –

1

я бы просто взять три параметра отдельно, пусть вызывающий выяснить, какая из них название, срок или статус

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

Теперь звонящие может определить, какой из них использует идентификаторы, атрибуты данных или все, что они хотят.

<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); 
+0

Я вижу, что вы пытаетесь сделать, и я могу закончить эту опцию.Мое единственное возражение против вашего решения заключается в том, что мне по-прежнему требуется внести вручную изменения в код коллекции, если я когда-либо решил добавить дополнительные поля ввода в форму. Любые мысли по этому поводу? Благодарим вас за быстрый ответ. –

+1

Вы имеете в виду, если вы добавите больше полей в объект 'Task'? То, что я сделал, отделило «Задачу» от формы точно так, чтобы вы могли изменить форму и не изменять «Задачу». Отправьте пример того, что вы имеете в виду, включая HTML –

+0

, добавленный пример «предлагаемого кода». –

-1

Я хотел бы использовать ассоциативный массив -

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

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

Это делает ваш массив семантически значимым и менее хрупким. Неважно, если вы расширите форму, если вы не измените имена, она будет продолжать работать.

Это также означает, что вам не нужно менять подпись вызова вашего конструктора при каждом расширении формы, вам нужно изменить тело, чтобы иметь дело с новыми элементами в массиве (или нет, поскольку вы так выберите).

+1

Cringe ... Пожалуйста, не используйте массивы как карты (или ассоциативный массив). Это терминология от разработчиков PHP, которые не изучили JavaScript. –

+1

Помните, что злоупотребление массивами как «ассоциативные массивы» сделает свойство 'length' бессмысленным. –

+0

Это должно быть должным образом задокументировано в любом случае, вряд ли будет большой нагрузкой. –

Смежные вопросы