Knockout js添加了一个新列表

时间:2015-03-07 02:21:04

标签: javascript jquery knockout.js

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

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

这是我在jave脚本中的viewmodel

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>

当我尝试单击“clickDeliveryOptions”时,它会在Firebug控制台上返回。

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

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

是否因为DeliveryOptions未初始化?我预计,当DeliveryCategory从DeliveryCategoryViewModel()初始化时...

有什么想法吗?谢谢!

1 个答案:

答案 0 :(得分:1)

小监督。轻松修复。

您从视图模型中调用了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);
}

请参阅下面的代码段

&#13;
&#13;
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());
});
&#13;
<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>
&#13;
&#13;
&#13;