使用knockout js动态添加新行
Dynamic Add New Row Using knockout js
使用 knockoutjs,我有 2 列 Qualification List 和 Marks。单击添加按钮后,我想生成新行并将(添加)按钮更改为更新按钮。
这是我的演示:https://jsfiddle.net/fjbrsvgn/3/
function Qualification(data) {
var self = this;
self.QualId = ko.observable(data.QualId);
self.QualName = ko.observable(data.QualName);
self.Marks = ko.observable(data.Marks);
}
function QualificationList(data) {
var self = this;
self.QualId = ko.observable(data.QualId);
self.QualName = ko.observable(data.QualName);
}
var QualificationViewModel = function () {
var self = this;
self.Marks = ko.observable();
self.Qualifications = ko.observableArray(Qualification);
self.QualificationLists = ko.observableArray([
{ QualName: 'Master', QualId: '0' },
{ QualName: 'Bachelor', QualId: '1' },
{ QualName: 'CA', QualId: '2' },
{ QualName: 'School Leaving', QualId: '3' }
]);
self.selectedQualName = ko.observable();
self.AddQualification = function () {
self.Qualifications.push({
QualList: "",
QualificationLists: "",
Marks: "",
selectedQualName: "",
});
};
self.SaveQualification = function () {
console.log(self.Qualifications());
};
};
$(document).ready(function () {
var qualificationViewModel = new QualificationViewModel();
ko.applyBindings(qualificationViewModel);
});
显示错误:初始化可观察数组时传递的参数必须是数组,或为空,或未定义。当我控制台 Qualifications 时我的预期结果需要显示 Qualification Name Qualification Id 和 Marks。
错误说
The argument passed when initializing an observable array must be an array, or null, or undefined.
而你正在这样做:
self.Qualifications = ko.observableArray(Qualification);
这将 函数 传递给可观察数组。这行不通。您可能希望将单个新限定条件设为 qualifications
的默认值。
self.Qualifications = ko.observableArray([new Qualification()]);
但是,我会将列表初始化为空,只有在有内容要添加时才让用户添加内容。这将保存屏幕 space.
以下是您尝试的改进版本:
- 将 "Add" 按钮移出了 table。这更有意义 - 当列表为空时它将可用,并且不会在每一行中重复。
- 添加了一个
if
绑定以在没有任何内容可显示时隐藏整个资格 table,以及一个 ifnot
绑定以在列表为空时显示信息段落。
- 清理了资格列表并从您的代码中删除了重复项。
- 它现在将整个资格对象存储在视图模型中,而不仅仅是 ID。这是通过 not 使用
optionsValue
绑定完成的,使您不必将资格详细信息复制到每个 Qualification
对象中。这也消除了对 "Update" 按钮的需要。
- 缺少的功能
deleteQualification
添加。
- HTML 中没有内联 "onkeypress" 事件处理程序。现在已经不是 1995 年了,不要编写内联事件处理程序。 Knockout 具有
event
绑定。
- 更好的对象和 属性 名称。只有构造函数应该以大写字母开头。
function checkKeyIsDigit(vm, event) {
return event.charCode >= 48 && event.charCode <= 57 || event.charCode === 46;
}
function Qualification(data) {
var self = this;
self.qual = ko.observable();
self.marks = ko.observable();
}
function EmployeeQualification() {
var self = this;
self.qualificationList = ko.observableArray([
{id: '0', name: 'Master'},
{id: '1', name: 'Bachelor'},
{id: '2', name: 'CA'},
{id: '3', name: 'School Leaving'}
]);
self.qualifications = ko.observableArray();
self.addQualification = function() {
self.qualifications.push(new Qualification());
};
self.deleteQualification = function(qual) {
self.qualifications.remove(qual);
};
self.saveQualification = function() {
console.log(self.qualifications());
};
}
var vm = new EmployeeQualification();
ko.applyBindings(vm);
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<h3>Employee Qualification</h3>
<hr>
<div class="col-md-12">
<p data-bind="ifnot: qualifications().length">No qualifications</p>
<table class="table-bordered" data-bind="if: qualifications().length">
<thead>
<tr>
<th class="text-center">Qualification</th>
<th class="text-center">Marks</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody data-bind="foreach: qualifications">
<tr>
<td>
<select class="form-control" data-bind="
value: qual,
options: $parent.qualificationList,
optionsText: 'name',
optionsCaption: '--Choose--'
"></select>
</td>
<td>
<input type="text" placeholder='Marks' data-bind="
value: marks,
event: {keypress: checkKeyIsDigit}
" class="form-control">
</td>
<td>
<button class="btn btn-default" data-bind="click: $parent.deleteQualification">Delete</button>
</td>
</tr>
</tbody>
</table>
<hr>
<div class="col-md-6">
<button class="btn btn-default" data-bind="click: addQualification">Add Qualification</button>
<button class="btn btn-default" data-bind="click: saveQualification">Submit</button>
</div>
</div>
<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
使用 knockoutjs,我有 2 列 Qualification List 和 Marks。单击添加按钮后,我想生成新行并将(添加)按钮更改为更新按钮。
这是我的演示:https://jsfiddle.net/fjbrsvgn/3/
function Qualification(data) {
var self = this;
self.QualId = ko.observable(data.QualId);
self.QualName = ko.observable(data.QualName);
self.Marks = ko.observable(data.Marks);
}
function QualificationList(data) {
var self = this;
self.QualId = ko.observable(data.QualId);
self.QualName = ko.observable(data.QualName);
}
var QualificationViewModel = function () {
var self = this;
self.Marks = ko.observable();
self.Qualifications = ko.observableArray(Qualification);
self.QualificationLists = ko.observableArray([
{ QualName: 'Master', QualId: '0' },
{ QualName: 'Bachelor', QualId: '1' },
{ QualName: 'CA', QualId: '2' },
{ QualName: 'School Leaving', QualId: '3' }
]);
self.selectedQualName = ko.observable();
self.AddQualification = function () {
self.Qualifications.push({
QualList: "",
QualificationLists: "",
Marks: "",
selectedQualName: "",
});
};
self.SaveQualification = function () {
console.log(self.Qualifications());
};
};
$(document).ready(function () {
var qualificationViewModel = new QualificationViewModel();
ko.applyBindings(qualificationViewModel);
});
显示错误:初始化可观察数组时传递的参数必须是数组,或为空,或未定义。当我控制台 Qualifications 时我的预期结果需要显示 Qualification Name Qualification Id 和 Marks。
错误说
The argument passed when initializing an observable array must be an array, or null, or undefined.
而你正在这样做:
self.Qualifications = ko.observableArray(Qualification);
这将 函数 传递给可观察数组。这行不通。您可能希望将单个新限定条件设为 qualifications
的默认值。
self.Qualifications = ko.observableArray([new Qualification()]);
但是,我会将列表初始化为空,只有在有内容要添加时才让用户添加内容。这将保存屏幕 space.
以下是您尝试的改进版本:
- 将 "Add" 按钮移出了 table。这更有意义 - 当列表为空时它将可用,并且不会在每一行中重复。
- 添加了一个
if
绑定以在没有任何内容可显示时隐藏整个资格 table,以及一个ifnot
绑定以在列表为空时显示信息段落。 - 清理了资格列表并从您的代码中删除了重复项。
- 它现在将整个资格对象存储在视图模型中,而不仅仅是 ID。这是通过 not 使用
optionsValue
绑定完成的,使您不必将资格详细信息复制到每个Qualification
对象中。这也消除了对 "Update" 按钮的需要。 - 缺少的功能
deleteQualification
添加。 - HTML 中没有内联 "onkeypress" 事件处理程序。现在已经不是 1995 年了,不要编写内联事件处理程序。 Knockout 具有
event
绑定。 - 更好的对象和 属性 名称。只有构造函数应该以大写字母开头。
function checkKeyIsDigit(vm, event) {
return event.charCode >= 48 && event.charCode <= 57 || event.charCode === 46;
}
function Qualification(data) {
var self = this;
self.qual = ko.observable();
self.marks = ko.observable();
}
function EmployeeQualification() {
var self = this;
self.qualificationList = ko.observableArray([
{id: '0', name: 'Master'},
{id: '1', name: 'Bachelor'},
{id: '2', name: 'CA'},
{id: '3', name: 'School Leaving'}
]);
self.qualifications = ko.observableArray();
self.addQualification = function() {
self.qualifications.push(new Qualification());
};
self.deleteQualification = function(qual) {
self.qualifications.remove(qual);
};
self.saveQualification = function() {
console.log(self.qualifications());
};
}
var vm = new EmployeeQualification();
ko.applyBindings(vm);
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<h3>Employee Qualification</h3>
<hr>
<div class="col-md-12">
<p data-bind="ifnot: qualifications().length">No qualifications</p>
<table class="table-bordered" data-bind="if: qualifications().length">
<thead>
<tr>
<th class="text-center">Qualification</th>
<th class="text-center">Marks</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody data-bind="foreach: qualifications">
<tr>
<td>
<select class="form-control" data-bind="
value: qual,
options: $parent.qualificationList,
optionsText: 'name',
optionsCaption: '--Choose--'
"></select>
</td>
<td>
<input type="text" placeholder='Marks' data-bind="
value: marks,
event: {keypress: checkKeyIsDigit}
" class="form-control">
</td>
<td>
<button class="btn btn-default" data-bind="click: $parent.deleteQualification">Delete</button>
</td>
</tr>
</tbody>
</table>
<hr>
<div class="col-md-6">
<button class="btn btn-default" data-bind="click: addQualification">Add Qualification</button>
<button class="btn btn-default" data-bind="click: saveQualification">Submit</button>
</div>
</div>
<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>