从Knockout Array创建HTML元素

时间:2017-06-09 20:34:47

标签: knockout.js

我有一个我在淘汰赛中使用的模型,其中包含不同的观察者。

self.myModel = { 
FirstName: ko.observable(), 
LastName: ko.observable(),
MiddleName : ko.observable(),
CatName: ko.observable(),
DogName: ko.observable()
... approx 80 properties
}

我想为模型中的每个属性创建一个html文本输入。

喜欢这样

<!--ko foreach: myModel-->
<span data-bind="text: myModel.item"></span>
<!--/ko-->

这是 Fiddle

如何使用foreach循环为每个可观察属性创建Html元素?

2 个答案:

答案 0 :(得分:1)

这是一个解决方案。我感兴趣的是使用rawData绑定来保持observable与其后的span同步。

&#13;
&#13;
function ViewModel(){
var self = this;

self.myModel = { 
    FirstName: ko.observable("Bert"), 
    LastName: ko.observable("Anderson"),
    MiddleName : ko.observable(),
    CatName: ko.observable(),
    DogName: ko.observable(),
    };
 
self.labels= ko.computed(function() {
    var array = $.map(self.myModel, function(value, key) {
    return [key];
    });
    return array
}, this);
    
self.myArray= ko.computed(function() {
    var array = $.map(self.myModel, function(value, index) {
    return [value];
    });
    return array
}, this);
}

var viewModel = new ViewModel();
ko.applyBindings(viewModel);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>



<!--ko foreach: myArray-->
<p>
 <strong data-bind="text: $root.labels()[$index()]"></strong> 
 <input data-bind="textInput: $rawData"/>
 <span data-bind="text: $data"></span>
</p>
<!--/ko-->
&#13;
&#13;
&#13;

所有这些都说不确定这是一个很好的方法,你可能想要查看模板和组件,以及淘汰映射插件。

答案 1 :(得分:1)

正如你所知,你可以使用Object.keys ...

来完成这项工作
<!-- ko foreach: { data: Object.keys(myModel), as: 'key' } -->
  <p>
    <input data-bind="textInput: $parent.myModel[key]"/>
    <span data-bind="text: key"></span>
  </p>
<!--/ko-->

然后,您可以更进一步,为迭代对象创建自定义绑定,例如此...

ko.bindingHandlers.foreachProperty = {
  init(el, valueAccessor) {
    const keyValuePairs = ko.pureComputed(() => {
      const raw = ko.unwrap(valueAccessor());
      return Object.keys(raw).map((key) => ({
        key,
        value: raw[key]
      }));
    });

    ko.applyBindingsToNode(el, {
      foreach: keyValuePairs
    });

    return { controlsDescendantBindings: true };
  }
}

ko.virtualElements.allowedBindings.foreachProperty = true;
<!-- ko foreachProperty: myModel -->
  <p>
   <input data-bind="textInput: value"/>
   <span data-bind="text: key"></span>
  </p>
<!--/ko-->

这是您自定义绑定的小提琴,https://jsfiddle.net/p1vfe6fu/9/

请注意,你所拥有的是一个物体,而不是阵列。