这是我的Knockout ViewModel
$(document).ready(
function () {
var Crime = function (CaseNumber, DateOfIncident, Description) {
this.CaseNumber = CaseNumber;
this.DateOfIncident = DateOfIncident;
this.Description = Description;
}
var crimes = function (items) {
var self = this;
//Data
self.items = ko.observableArray(items)
//operations
self.addCrime = function () {
if ($("#AddCrimeForm").valid()) {
self.crime = new Crime($("#CaseNumber").val(), $("#DateOfIncident").val(), $("#Description").val());
//var JSONObj = { CaseNumber: $("#CaseNumber").val(), DateOfIncident: $("#DateOfIncident").val(), Description: $("#Description").val() };
self.items.push(this.crime);
$("#CaseNumber").val("");
$("#DateOfIncident").val("");
$("#Description").val("");
}
}
self.removeCrime = function (item) {
self.items().remove(item);
}
}
var initialData = new Array();
ko.applyBindings(crimes(initialData), $("#CrimeList")[0])
}
);
以下是我在HTML中的视图:
<form id="AddCrimeForm">
<div class="panel panel-success">
<div class="panel-heading">
<div class="form-horizontal">
<div class="row">
<div class="col-lg-11">Add a crime incident to the list</div>
<div class="col-lg-1">
<button type="button" class="btn btn-success btn-xs" onclick="addCrime()"><i class="fa fa-plus"></i> Add</button>
</div>
</div>
</div>
</div>
<div class="panel-body">
<div class="form-horizontal">
<div class="row">
<div class="col-lg-6">
<input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Id" name="Id" type="hidden" value="">
<div class="form-group">
<label class="control-label col-md-4" for="CaseNumber">Case Number</label>
<div class="col-md-8">
<input class="form-control text-box single-line" data-val="true" data-val-required="The Case Number field is required." id="CaseNumber" name="CaseNumber" type="text" value="">
<span class="field-validation-valid" data-valmsg-for="CaseNumber" data-valmsg-replace="true"></span>
</div>
</div>
<div class="form-group">
<label class="control-label col-md-4" for="DateOfIncident">Date Of Incident</label>
<div class="col-md-8">
<input class="form-control text-box single-line valid" data-val="true" data-val-required="The Date of Incident field is required." id="DateOfIncident" name="DateOfIncident" type="date" value="">
<span class="field-validation-valid" data-valmsg-for="DateOfIncident" data-valmsg-replace="true"></span>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="control-label col-md-4" for="Description">Description</label>
<div class="col-md-8">
<textarea class="form-control text-box multi-line" data-val="true" data-val-required="The Description field is required." id="Description" name="Description"></textarea>
<span class="field-validation-valid" data-valmsg-for="Description" data-valmsg-replace="true"></span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<table class="table table-striped table-hover " id="CrimeList">
<thead>
<tr>
<th>Case Number</th>
<th>Date of Incident</th>
<th>Description</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: $data.CaseNumber" class="col-lg-2">Column content</td>
<td data-bind="text: $data.DateOfIncident" class="col-lg-2">Column content</td>
<td data-bind="text: $data.Description" style="text-wrap: normal" class="col-lg-7">Column content</td>
@*<td></td>
<td></td>
<td></td>*@
<td style="text-align: center" class="col-lg-1">
<a href="#" data-bind="click: $root.removeCrime()"><i class="fa fa-trash-o"></i> Remove</a>
</td>
</tr>
</tbody>
</table>
添加项目时出现的错误与表格中“删除”链接的绑定有关,如下所示:
第58行第363行未处理的异常
http://localhost:49803/Scripts/KnockOut/knockout-3.0.0.js
0x800a138f - JavaScript运行时错误:无法获取属性 'removeCrime'的undefined或null引用
现在,我不确定这里的问题是什么,因为我应该绑定到root,因为removeCrime方法驻留在ViewModel的根目录中?
答案 0 :(得分:0)
您正在窗口对象上设置removeCrime函数,因为犯罪函数正在全局范围内执行,并且这指向窗口。
在设置viewModel时尝试使用new关键字。这将创建新对象并将其设置为此对象。 如果要在knockout之外调用它,还应该将add方法附加到窗口。 另一个错误是你在JS数组上调用remove()而不是在observable Array上。 这是工作代码:
$(document).ready(
function () {
var Crime = function (CaseNumber, DateOfIncident, Description) {
this.CaseNumber = CaseNumber;
this.DateOfIncident = DateOfIncident;
this.Description = Description;
}
var crimes = function (items) {
var self = this;
//Data
self.items = ko.observableArray(items)
//operations
window.addCrime = function () {
if ($("#AddCrimeForm")) {
crime = new Crime($("#CaseNumber").val(), $("#DateOfIncident").val(), $("#Description").val());
//var JSONObj = { CaseNumber: $("#CaseNumber").val(), DateOfIncident: $("#DateOfIncident").val(), Description: $("#Description").val() };
self.items.push(this.crime);
$("#CaseNumber").val("");
$("#DateOfIncident").val("");
$("#Description").val("");
}
}
self.removeCrime = function (item) {
self.items.remove(item);
}
}
var initialData = new Array();
ko.applyBindings(new crimes(initialData), $("#CrimeList")[0])
}
);
答案 1 :(得分:0)
我检查你的代码,据我所知你错过了淘汰赛的真正力量。如果你使用淘汰赛,我认为不需要使用jquery选择器访问输入字段的值。
我创建了一个js小提琴,请检查:
javascript代码看起来像:
function crimeRecord(data)
{
var self = this;
self.caseNumber = data.CaseNumber;
self.dateOfIncident = data.DateOfIncident;
self.description = data.Description;
}
//Main view model
function viewModel()
{
var self = this;
self.crimeRecords = ko.observableArray();
self.newCrimeRecord = ko.observable(new crimeRecord({}));
self.addRecord = function(){
self.crimeRecords.push(self.newCrimeRecord());
self.newCrimeRecord(new crimeRecord({}));
};
self.removeRecord = function(record){
self.crimeRecords.remove(record);
};
}
$(function(){
ko.applyBindings(new viewModel());
});
修改 - 1
正如您在关于jquery验证的评论中提到的那样,没有必要重写任何验证逻辑,您可以使用此viewmodel进行jquery验证。以下是使用它的一种方法:
....
self.addRecord = function(){
if($("form").valid())
{
self.crimeRecords.push(self.newCrimeRecord());
self.newCrimeRecord(new crimeRecord({}));
}
else
$("form").showErrors();
};
...
或者您可以使用Knockout Validation。