JavaScript является многоцелевым языком, вы, конечно, можете решить его по-разному.При переключении на функциональное программирование ответ очень прост: используйте функции!Проблема с вашим примером заключается в следующем: он настолько урезан, что вы можете сделать то же самое, что и всего лишь с 3 строками:
// getValue :: DOMNode -> String
const getValue = field => field.value;
// readForm :: Array DOMNode -> Array String
const readForm = formFields => formFields.map(getValue);
readForm(Array.from(document.querySelectorAll('input, textarea, select')));
// -> ['Value1', 'Value2', ... 'ValueN']
Критическая вещь: как реализуется Field::getValue()
, что делаетэто возврат ?Или точнее: чем DropdownField::getValue()
отличается от AutocompleteField::getValue()
и, например, NumberField::getValue()
?Все ли они просто возвращают значение?Они возвращают пару имени и значения?Они даже нуждаются в , чтобы отличаться?
Вопрос заключается в том, отличаются ли ваши Field
классы и их наследующие классы из-за того, как работают их методы getValue()
, или они скорееотличаются из-за другой функциональности у них есть?Например, функциональность «автозаполнения» текстового поля не связана (или не должна) быть привязана к тому, как из него берется значение.
Если вам действительно нужно прочитать значения по-другому, выможет реализовать функцию, которая принимает карту / словарь / объект / POJO из {fieldtype: readerFunction}
пар:
/* Library code */
// getTextInputValue :: DOMNode -> String
const getTextInputValue = field => field.value;
// getDropdownValue :: DOMNode -> String
const getDropdownValue = field => field.options[field.selectedIndex].value;
// getTextareaValue :: DOMNode -> String
const getTextareaValue = field => field.textContent;
// readFieldsBy :: {String :: (a -> String)} -> DOMNode -> Array String
readFieldsBy = kv => form => Object.keys(kv).reduce((acc, k) => {
return acc.concat(Array.from(form.querySelectorAll(k)).map(kv[k]));
}, []);
/* Code the library consumer writes */
const readMyForm = readFieldsBy({
'input[type="text"]': getTextInputValue,
'select': getDropdownValue,
'textarea': getTextareaValue
});
readMyForm(document.querySelector('#myform'));
// -> ['Value1', 'Value2', ... 'ValueN']
Примечание: я намеренно не упомянул такие вещи, как монада ввода / вывода, потому что это сделало бы вещи болеесложный, но вы можете посмотреть его.