从knockout.mapping

时间:2016-08-23 15:27:31

标签: knockout.js knockout-mapping-plugin

以下是我的代码的一个非常简化的版本..

我的HTML代码:

<div class="container body-content" data-bind="foreach:base">
    <div class="col-md-12" data-bind="with:s">
        <div class="col-md-4"><pre data-bind="text:sp"></pre></div>
        <div class="col-md-7">
            <div class="row" data-bind="foreach: spd">
                <input type="text" class="form-control" data-bind="value:value, valueUpdate: 'input'" />
                <button data-bind="click: $parent.addval">add</button><button data-bind="click: $parent.removeval">rem</button>
            </div>
        </div>
    </div>
</div>

我的Javascript代码:

<script src="knockout-3.2.0.js"></script>
            <script src="knockout.mapping.js"></script>
            <script>
                var data = [{
                    "s": {
                        "sp": "abc",
                        "spd": [
                          {
                              "value": ""
                          }
                        ]
                    },
                    "type": "xyz",
                 }];
                var AppScope = function () {

                    function BaseViewModel() {
                        var self = this;
                        self.base = ko.observableArray();
                        self.base(ko.mapping.fromJS(data)());
                    }
                    ko.applyBindings(new BaseViewModel());
                }();
            </script>

&#39;数据&#39;数组来自服务器,并且具有非常复杂的数据结构,因此无法使用$ root。 使用的样式here可能是答案,但还不能解决..

除按钮外,代码有效。我想了解如何将{value:&#34;&#34;}对象添加到&#39; spd&#39;下的数组中。按下addval和remval函数删除它。

真诚感谢所有帮助 感谢

1 个答案:

答案 0 :(得分:0)

这是一种奇怪的设置,但我只是按照你提供的方式进行。 spd最初有一个空值的成员。输入框允许您更改值。 add按钮将值复制到新条目中。 remove按钮删除当前条目。

最棘手的一点是找出从self.basespd observableArray的结构。更新:我修改了点击绑定处理程序以获取s上下文($parent),以便他们知道他们正在使用哪sspd

我将上下文从$parent更改为$root,因为在addval级别创建removevals函数对我没有意义

var data = [{
  "s": {
    "sp": "abc",
    "spd": [{
      "value": ""
    }]
  },
  "type": "xyz",
}];
var AppScope = function() {

  function BaseViewModel() {
    var self = this;
    self.base = ko.observableArray();
    self.base(ko.mapping.fromJS(data)());
    self.addval = function(sData, data) {
      sData.spd.push({value: ko.observable(data.value())});
    };
    self.removeval = function(sData, data) {
      sData.spd.remove(data);
    }

  }
  ko.applyBindings(new BaseViewModel());
}();
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div class="container body-content" data-bind="foreach:base">
  <div class="col-md-12" data-bind="with:s">
    <div class="col-md-4"><pre data-bind="text:sp"></pre>
    </div>
    <div class="col-md-7">
      <div class="row" data-bind="foreach: spd">
        <input type="text" class="form-control" data-bind="value:value, valueUpdate: 'input'" />
        <button data-bind="click: (data) => $root.addval($parent, data)">add</button>
        <button data-bind="click: (data) => $root.removeval($parent, data)">rem</button>
      </div>
    </div>
  </div>
</div>

如果你想使用不显眼的事件处理(并且你有jQuery)做同样的事情,相关的代码可能如下所示:

function BaseViewModel() {
    var self = this;
    self.base = ko.observableArray();
    self.base(ko.mapping.fromJS(data)());
  }
  ko.applyBindings(new BaseViewModel());

  $('body').on('click', '.add-btn', function() {
    const context = ko.contextFor(this);
    const data = ko.dataFor(this);
    const s = context.$parent;

    s.spd.push({
      value: ko.observable(data.value())
    });
  });

  $('body').on('click', '.remove-btn', function() {
    const context = ko.contextFor(this);
    const data = ko.dataFor(this);
    const s = context.$parent;

    s.spd.remove(data);
  });