Я пытаюсь создать конструктор динамических форм. Пользователь может указать, сколько текстовых полей он хочет в каждой строке. Скажем, я указал, что моя форма должна иметь 2 текстовых поля на строку, тогда я ожидаю, что будет отображаться следующее:
<div class = "form-group row">
<div class = "col-6">
<input class = "form-control" type = "color" value = "#563d7c" id = "example-color-input">
</div>
<div class = "col-6">
<input class = "form-control" type = "color" value = "#563d7c" id = "example-color-input">
</div>
</div>
В моем файле .jsx я получаю JSON, который содержит 4 имени, используя это, я хотел бы перебрать и создать 4 текстовых поля, по 2 в каждой строке.
static buildForm(fields, isSingleColumn) {
let questions = fields().length;
return (
<form ref = "form" data-bind = "foreach: fields">
<div class = "row">
</div>
</form>
);
}
Я надеялся, что int за пределами return в buildForm будет увеличиваться каждый раз, когда он создает текстовое поле, а затем, если он достиг последнего, т.е. 2-го текстового поля, закройте строку div, однако я не уверен, как это сделать, поскольку я использую привязка данных.
Это правильный способ сделать это или их подходы / решения лучше?
Я бы не стал смешивать нокаут и реакцию, это просто лишняя головная боль. Либо шаблоны нокаута выполнят свою работу, либо, в ответ, установите число как состояние и зациклите вывод





Вместо каких-либо взломов nth-textbox в вашей разметке для определения конца строки я бы сначала разделил их на отдельные массивы в модели представления. Затем вы можете просто использовать вложенную привязку foreach для отражения структуры вашей модели:
function viewModel() {
var self = this;
self.fields = ko.observableArray(["field 1", "field 2", "field 3", "field 4", "field 5"]);
self.chunkSize = ko.observable(2);
self.itemChunks = ko.computed(function() {
var chunks = [];
var items = self.fields().slice(); //shallow copy
while (self.chunkSize() && items.length > self.chunkSize()) {
var chunk = [];
for (var i = 0; i < self.chunkSize(); i++) chunk.push(items.shift());
chunks.push(chunk);
}
chunks.push(items); //add any remaining
return chunks;
});
}
ko.applyBindings(new viewModel());.row {
border: 1px dotted silver;
padding: 2px;
}
.col-6 {
display: inline-block;
}<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
chunk size (fields per row)<input type = "text" data-bind = "textInput: chunkSize" />
<br/>
<form ref = "form" data-bind = "foreach: itemChunks">
<div class = "row" data-bind = "foreach: $data">
<div class = "col-6">
<input type = "text" data-bind = "textInput: $data" />
</div>
</div>
</form>Вместо этого используйте шаблоны.
<div data-bind = "foreach: formFields">
<div class = "col-6">
<input class = "form-control" type = "color" value = "#563d7c" id = "example-color-input">
</div>
</div>
в вашем модальном объекте на основе ввода заполнить поля формы.
Почему вы смешиваете код React и Knockout?