У меня есть таблица данных, которая отображается через вызов API. Он отображает 4 значения из исходного объекта. Меня в основном волнует значение name
, так как это то, что важно позже в почтовом запросе.
Каждая строка в таблице имеет флажок. Когда флажок установлен (true
), имя, связанное с этим флажком, добавляется к объекту с именем selectedFields
в качестве объекта. Например, если я устанавливаю флажок с именем id
, он создает хранилище объектов, например:
"selectedFields": {
"id" : {}
}
Это работает хорошо и хорошо. Однако я добавил 3 поля ввода, связанные с каждым name
. Входы lengthType
, size
, maxArrayElements
, которые, конечно, выбираются пользователем.
У меня возникли проблемы с добавлением этих значений обратно к объекту, чтобы он выглядел так:
"selectedFields": {
"id": {
lengthType: Variable,
size: 1,
maxArrayElements: 1
},
"price": {
lengthType: Fixed,
size: 10,
maxArrayElements: 1
}
}
Как я могу добавить эти 3 значения обратно к созданному объекту name
, чтобы он выглядел как в приведенном выше примере?
Я не хочу публиковать стену кода, поэтому я публикую функцию флажка, которая обрабатывает создание объекта selectedFields
с соответствующим выбранным names
. Я подозреваю, что входные значения должны быть каким-то образом добавлены сюда, но я не уверен.
checkbox = ({ name, isChecked }) => {
//handle check box of each fieldName
const obj = this.state.fieldNames.find(field => field.name === name);
if (isChecked === true) {
//checked conditional
this.setState(
{
selectedFields: {
...this.state.selectedFields,
[name]: {
...obj
}
}
},
() => {
console.info(
"callback in isChecked if conditional",
this.state.selectedFields
);
}
);
} else {
const newSelectedFields = this.state.selectedFields;
delete newSelectedFields[name];
this.setState(
{
selectedFields: newSelectedFields
},
() => {
console.info(
`box unchecked, deleted from object --->`,
this.state.selectedFields
);
}
);
}
};
Вам нужно будет сделать первый выбор в раскрывающемся списке для просмотра данных.
Вам нужно изменить несколько вещей, потому что нигде не указано, где назначать новое состояние вне объекта корневого состояния.
Обработчики в вашем Index.js:
Ваши обработчики событий изменения не ищут имя объекта, чтобы определить, существует он или нет. Если вы хотите добавить его к указанному дочернему объекту, убедитесь, что он там есть.
Мы настраиваем обработчики так, чтобы они брали имя объекта и setState с object.assign
для этого конкретного объекта, если он существует:
Примечание: поскольку lengthType
не имеет свойства name
, мы просто предоставляем ему строку. e.currentTarget
предоставит параметр span, а не корневой элемент Dropdown
, поэтому даже предоставление свойства name
этому компоненту не позволит нам использовать e.currentTarget.name
— вы можете проконсультироваться с Документация семантического пользовательского интерфейса, если вы предпочитаете что-то другое. Я быстро просмотрел его, но не хотел глубоко погружаться.
handleChangeEvent = (e, obj_name) => {
if (this.state.selectedFields[obj_name]) {
let selectedFields = Object.assign({}, this.state.selectedFields);
selectedFields[obj_name] = Object.assign(
this.state.selectedFields[obj_name],
{ [e.target.name]: e.target.value }
);
this.setState({ selectedFields });
}
};
onLengthTypeChange = (e, obj_name) => {
if (this.state.selectedFields[obj_name]) {
let selectedFields = Object.assign({}, this.state.selectedFields);
selectedFields[obj_name] = Object.assign(
this.state.selectedFields[obj_name],
{ lengthType: e.currentTarget.textContent }
);
this.setState({ selectedFields });
}
};
Вышеупомянутое, конечно, не будет работать, если вы не настроите свои события onChange
на своих компонентах так, чтобы в дополнение к вашему объекту события они также отправляли имя вашего объекта.
Обработчики в файле компонента:
Примечание: Это было странно, потому что в вашем файле Index.js
вы, кажется, наполовину сделали это с lengthType
, но не передали дополнительные данные. Вы не можете просто передать параметры в обработчик — чтобы заставить его работать, вам нужно передать анонимную функцию в свойства onChange
, которые будут принимать событие и передавать его функциям обработчика с участием имя вашего объекта:
<Table.Cell>
<Dropdown
placeholder = "Pick a length Type:"
clearable
selection
search
fluid
noResultsMessage = "Please search again"
label = "lengthType"
multiple = {false}
options = {lengthTypeOptions}
header = "Choose a Length Type"
onChange = {e => onLengthTypeChange(e, name)}
value = {lengthType}
required
/>
</Table.Cell>
<Table.Cell>
<Input
onChange = {e => handleChangeEvent(e, name)}
value = {this.state.size}
type = "number"
name = "size"
min = "1"
placeholder = "1"
required
/>
</Table.Cell>
<Table.Cell>
<Input
onChange = {e => handleChangeEvent(e, name)}
value = {this.state.maxArrayElements}
type = "number"
name = "maxArrayElements"
placeholder = "1"
min = "1"
max = "100"
required
/>
</Table.Cell>
Как только эти вещи будут скорректированы, код обновит указанные свойства дочерних объектов после того, как соответствующий флажок будет выбран.
Я не стал настраивать сохранять предыдущее состояние если снимите флажок а потом чек об оплате ящик. Это не было указано в вашем вопросе, и я не хочу делать предположения.
Скорректированная песочница кода: https://codesandbox.io/s/createqueryschema-table-rewrite-bwvo4?fontsize=14
В вашем начальном состоянии ваш selectedFields
объявляется как Array
, а затем он быстро превращается в Object
при установке любого флажка. Я бы предложил этого не делать. Изменение типов данных в свойстве во время работы приложения может привести к большим проблемам.
Когда флажок установлен, вы предоставляете функцию checkbox
из вашего файла Index.js
. Это просто называется box
в вашем компоненте. Я бы предложил сохранить имена свойств и эквивалент состояния при передаче от родителя к дочернему элементу. Кому-то гораздо, намного, намного проще прийти и поддерживать, если это необходимо, не говоря уже о том, что легче сохранить собственное здравомыслие.
Вышеупомянутая функция checkbox
берет свойства от дочернего элемента и передает их родителю. Это будет место для передачи собранных данных в кеш на родительском объекте, в локальное/сеансовое хранилище или во что угодно, что вы хотите сделать со своими данными. Вместо этого вы могли бы написать код для эффекта: если флажок установлен, когда обработчик ввода вызывается делать, сохранение, но я бы сказал, что это, вероятно, было бы лучше на render
, так как экран все равно постоянно обновляется, и у вас есть функция checkbox
охотно проходящий реквизит в настоящее время. Это предпочтение, так что это ваш выбор
Удачи! Надеюсь, это помогло!
У меня возникли некоторые проблемы с получением selectedFields
желаемого типа/структуры данных, как я упоминал выше. Обработчики изменений тоже нужно переделывать?
@ DJ2 они не должны быть. Настройка структуры данных в основном выполняется в файле индекса. Что вам нужно сделать, так как вместо того, чтобы находить свойство объекта selectedFields
, вы ищете объект в массиве для обновления, вероятно, было бы проще всего: а) filter
для объекта, настроить его и заменить это в исходном массиве или б) reduce
исходный массив и заменить его возвращенным массивом.
Не могли бы вы поделиться основным примером, если это возможно?
@DJ2 Я могу, но сегодня не смогу. Я работаю над несколькими разными вещами. Тем временем, возможно, стоит создать еще один вопрос.
Итак, я опубликовал новый вопрос в другом месте и получил желаемую структуру, но я думаю, что обработчики изменений необходимо обновить, поскольку они больше не добавляются к проверяемому объекту name
. codeandbox.io/s/o7jnvlnj0y
@ DJ2 Извиняюсь, это вылетело из головы. Как-нибудь сегодня посмотрю.
не беспокойтесь, сам name
больше не является объектом, поэтому его нужно добавить в тот же объект, который содержит name
Я изменил метод onLengthTypeChange
, но все еще не могу получить входные данные для добавления обратно к проверенному [obj_name]
Как бы вы сохранили предыдущий объект, если флажок не отмечен/отмечен?
Вы затронули каждую часть, с которой я боролся / задавал вопросы. Спасибо. По вашей первой рекомендации я только что узнал, что
selectedFields
должен быть массивом объектов (выбранных флажков)."selectedFields": [ { "name": "nameOne", "lengthType": "fixed" .. etc } , { "name": "nameTwo" .. etc } ]