Knockout js 添加新列表

Knockout js add a new list

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

但是我无法让我的添加功能正常工作,它一直抱怨我的列表未定义。

这是我在 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 时,它 return 在 Firebug 控制台上。

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

我尝试了不同的方法,例如 click:$root.addDeliveryOptions,还尝试添加 addDeliveryOptions 函数作为原型(例如 DeliveryCategory.prototype.addDeliveryOptions(...)),但仍然出现 Typeerror...

是不是DeliveryOptions没有初始化?我预计会在从 DeliveryCategoryViewModel() 初始化 DeliveryCategory 时...

有什么想法吗?谢谢!

小疏忽。轻松修复。

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

这是因为您从未将可观察数组直接添加到此视图模型中。您使用构造函数创建对象以使用 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>