Knockout js 添加一个新列表

Knockout js add a new list

本文关键字:一个 新列表 列表 js 添加 Knockout      更新时间:2023-09-26

我正在尝试创建一个带有列表的表单,该列表可以动态添加列表!

但是,我只是无法让我的添加函数工作,并且它一直抱怨我的列表未定义。

这是我在 jave 脚本中的视图模型

function DeliveryCategoryViewModel() {
    var self = this;
    self.DeliveryCategory = ko.observable(new DeliveryCategory(1, "new Name", [new DeliveryOption("first"), new DeliveryOption("second")]));
    self.addDeliveryOptions = function () {
        self.DeliveryOptions.push(new DeliveryOption("new Option"));
    }
    self.removeDeliveryOptions = function (option) {
        self.DeliveryCategory.remove(option);
    }
}

这些是保存数据的实际模型

function DeliveryCategory(id, name, option) {
    this.Id = id;
    this.Name = name;
    this.DeliveryOptions = ko.observableArray(option);
}
function DeliveryOption(name) {

    this.Id = "2";
        this.Name = name;
}

$(document).ready(function () {
    ko.applyBindings(new DeliveryCategoryViewModel());
});

这是我的表格

<div id="newDelCategory">
        <input data-bind="value:DeliveryCategory().Id" type="hidden" />
        <label class="newDelCategoryLabel">New delivery category name: </label>
    <input type="text" data-bind="value:DeliveryCategory().Name" class="newDelCategoryText" id="newDelCategoryText" placeholder="Delivery category name" />
</div>
<div id="addOption">
    <a id="addOptionLink" href="#" data-bind="click:addDeliveryOptions" class="link">+Add delivery option</a>
</div>
<div id="deliveryOptionContent" data-bind="foreach: DeliveryCategory().DeliveryOptions">
    <div class="newDelOption">
        <input data-bind="value:$data.Id" type="hidden" />
        <div class="divider"></div>
        <label class="newDelOptionLabel">New delivery option name: </label>
        <input type="text" data-bind="value:$data.Name" class="categoryName" id="newDelOptionText" placeholder="Delivery option name" />
        <a id="removeOptionLink" data-bind="click:$parent.removeDeliveryOptions" class="link removeOptionLink">Remove</a>
    </div>
</div>

当我尝试单击click:addDeliveryOptions时,它会返回Firebug控制台。

TypeError: self.DeliveryCategory.DeliveryOptions is undefined
self.DeliveryCategory.DeliveryOptions.push(new DeliveryOption("new Option"));

我尝试了不同的东西,例如click:$root.addDeliveryOptions,并且还尝试添加addDeliveryOptions函数作为原型(例如DeliveryCategory.prototype.addDeliveryOptions(...)),但仍然得到Typeerror...

是因为交付选项未初始化吗?我预计这将是当交付类别从交付类别视图模型()初始化时...

知道吗?谢谢!

小监督。轻松修复。

您调用了push并从视图模型中remove了可观察数组,但它作为视图模型的直接成员存在。

这是因为您永远不会将可观察数组直接添加到此视图模型。使用构造函数创建要与 DeliveryCategory 一起观察的对象。该对象上的属性之一是可观察数组DeliveryOptions。若要从此范围访问可观察数组,必须在运行任何数组方法之前评估DeliveryCategory以访问其属性DeliveryOptions。所以,取而代之的是:

self.addDeliveryOptions = function () {
    self.DeliveryOptions.push(new DeliveryOption("new Option"));
}
self.removeDeliveryOptions = function (option) {
    self.DeliveryCategory.remove(option);
}

解决方案:

self.addDeliveryOptions = function() {
    self.DeliveryCategory().DeliveryOptions.push(new DeliveryOption("new Option"));
}
self.removeDeliveryOptions = function(option) {
    self.DeliveryCategory().DeliveryOptions.remove(option);
}

请参阅下面的代码片段

function DeliveryCategoryViewModel() {
  var self = this;
  self.DeliveryCategory = ko.observable(new DeliveryCategory(1, "new Name", [new DeliveryOption("first"), new DeliveryOption("second")]));
  self.addDeliveryOptions = function() {
    self.DeliveryCategory().DeliveryOptions.push(new DeliveryOption("new Option"));
  }
  self.removeDeliveryOptions = function(option) {
    self.DeliveryCategory().DeliveryOptions.remove(option);
  }
}
function DeliveryCategory(id, name, option) {
  this.Id = id;
  this.Name = name;
  this.DeliveryOptions = ko.observableArray(option);
}
function DeliveryOption(name) {
  this.Id = "2";
  this.Name = name;
}
$(document).ready(function() {
  ko.applyBindings(new DeliveryCategoryViewModel());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="newDelCategory">
  <input data-bind="value:DeliveryCategory().Id" type="hidden" />
  <label class="newDelCategoryLabel">New delivery category name:</label>
  <input type="text" data-bind="value:DeliveryCategory().Name" class="newDelCategoryText" id="newDelCategoryText" placeholder="Delivery category name" />
</div>
<div id="addOption">
  <a id="addOptionLink" href="#" data-bind="click:addDeliveryOptions" class="link">+Add delivery option</a>
</div>
<div id="deliveryOptionContent" data-bind="foreach: DeliveryCategory().DeliveryOptions">
  <div class="newDelOption">
    <input data-bind="value:$data.Id" type="hidden" />
    <div class="divider"></div>
    <label class="newDelOptionLabel">New delivery option name:</label>
    <input type="text" data-bind="value:$data.Name" class="categoryName" id="newDelOptionText" placeholder="Delivery option name" />
    <a href="#" id="removeOptionLink" data-bind="click:$parent.removeDeliveryOptions" class="link removeOptionLink">Remove</a>
  </div>
</div>

相关文章: