使用KO的动态表单构建器

时间:2018-11-15 21:25:13

标签: reactjs knockout.js

我正在尝试创建动态表单构建器。用户可以指定每行要多少个文本框。假设我指定我的表单每行必须有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文件中,我接收到一个包含4个名称的JSON,我想使用它来遍历并创建4个文本行,每行2个。

  static buildForm(fields, isSingleColumn) {
    let questions = fields().length;

    return (
        <form ref="form" data-bind="foreach: fields">
            <div class="row">

            </div>
        </form>
    );
}

我希望buildForm内的返回值之外有一个int值,以使其每次创建文本框时都递增,然后,如果到达最后一个即第二个文本框,则关闭div行,但是我不确定如何执行此操作作为即时通讯使用数据绑定。

这是正确的方法还是更好的方法/解决方案?

2 个答案:

答案 0 :(得分:0)

我不会在标记中使用任何nth-textbox hack来确定行的结尾,而是先将它们拆分为视图模型中的单独数组。然后,您可以简单地使用嵌套的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>

答案 1 :(得分:0)

改为使用模板。

<div data-bind="foreach: formFields">
    <div class="col-6">
    <input class="form-control" type="color" value="#563d7c" id="example-color-input">
  </div>
</div>

在“对象”模式中根据输入填充formFields。