【问题标题】:Add and remove object from array when the observable created from knockout.mapping当从 knockout.mapping 创建可观察对象时,从数组中添加和删除对象
【发布时间】:2016-12-30 12:27:47
【问题描述】:

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

我的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>

'data'数组来自服务器,数据结构非常复杂,所以$root不能用。 here 使用的样式可能是答案,但还无法弄清楚..

除了按钮之外,代码都可以工作。我想了解如何将 {value:""} 对象添加到“spd”下的数组中,并在按下 addval 和 remval 函数时将其删除。

真诚感谢所有帮助 谢谢

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin


    【解决方案1】:

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

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

    我将上下文从$parent 更改为$root,因为在s 级别创建addvalremoveval 函数对我来说没有意义。

    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);
      });
    

    【讨论】:

    • 谢谢,但是不行。。我的数据数组有多个对象,我这里只提供了一个来展示数据结构。此外,来自服务器的实际对象具有非常复杂的数据结构,因此不能使用 $root。必须使用knockoutjs.com/documentation/unobtrusive-event-handling.html 之类的东西,但不幸的是无法弄清楚..
    • 现在怎么样?点击处理程序将$parent(即s,来自with 绑定)和数据项传递给addvalremoveval
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 2018-03-04
    • 2023-04-06
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    相关资源
    最近更新 更多