使用 Knockoutjs 在客户端添加和删除项目
Add and remove Items on client side with Knockoutjs
我一直在努力制作一个交互式表单,其中一个视图模型具有一组项目。我想从该集合中动态 add/remove 项目。
我发现很难找到达到这种深度的示例,而且大多数示例通常都停留在更直接的实现上,但是我遇到了 This post which pretty much explains what i'm doing with this brilliant jsfiddle,其中 json使用knockout mapping plugin拉取然后映射。
var company;
function PersonViewModel(data) {
var personMapping = {
'ignore': ['twitter', 'webpage'],
'copy': ['age'],
'lastName': {
'create': function (options) {
return ko.observable(options.data.toUpperCase());
}
}
};
ko.mapping.fromJS(data, personMapping, this);
this.fullName = ko.computed(function () {
return this.firstName() + ' ' + this.lastName();
}, this);
}
function CompanyViewModel(data) {
var companyMapping = {
'ignore': ['address', 'website'],
'name': {
'create': function (options) {
return ko.observable(options.data.toUpperCase());
}
},
'employees': {
key: function (data) {
return ko.utils.unwrapObservable(data.personId);
},
create: function (options) {
return new PersonViewModel(options.data);
}
}
};
ko.mapping.fromJS(data, companyMapping, this);
}
我不知道如何实现的是 如何以及在何处 准确地添加 'addEmployee' 和 'removeEmployee' 函数?以及如何将它们绑定到按钮?
提前致谢!
您可以将这些函数添加到您的 CompanyViewModel
。
CompanyViewModel
...
this.addEmployee = function () {
this.employees.push(new PersonViewModel({
firstName: 'New',
lastName: 'Employee',
age: 777,
}));
};
this.removeEmployee = function () {
this.employees.pop();
};
HTML
....
<div data-bind="click: addEmployee">Add Employee</div>
<div data-bind="click: removeEmployee">Remove Employee</div>
...
添加这些内容的合理位置是您的 CompanyViewModel
。例如,像这样:
function CompanyViewModel(data) {
var self = this;
var companyMapping = {
// ...as before
};
self.addEmployee = function () {
// as an example, we are just adding a static new employee
self.employees.push(new PersonViewModel({
lastName: "new",
firstName: "employee",
age: 10
}));
}
// important, with how we are binding the function, we expect the
// argument, e, to be the employee to remove
self.removeEmployee = function (e) {
self.employees.remove(e);
}
ko.mapping.fromJS(data, companyMapping, this);
}
添加绑定,可以这样操作:
<div id="company">
<h1 data-bind="text: name"></h1>
<h2>Employees</h2>
<input type="button" value="add" data-bind="click: addEmployee" />
<table>
<thead>
<tr>
<th>Full name</th>
<th>Last name</th>
<th>First name</th>
<th>Age</th>
</tr>
</thead>
<tbody data-bind="foreach: employees">
<tr>
<td data-bind="text: fullName"></td>
<td data-bind="text: lastName"></td>
<td data-bind="text: firstName"></td>
<td data-bind="text: age"></td>
<td>
<input type="button" value="x" data-bind="click: $parent.removeEmployee" />
</td>
</tr>
</tbody>
</table>
</div>
这将为每个员工添加一个 add
按钮以及一个删除 x
按钮,该按钮调用父 CompanyViewModel
传递的 removeEmployee
函数员工。
这是更新后的 fiddle
我一直在努力制作一个交互式表单,其中一个视图模型具有一组项目。我想从该集合中动态 add/remove 项目。
我发现很难找到达到这种深度的示例,而且大多数示例通常都停留在更直接的实现上,但是我遇到了 This post which pretty much explains what i'm doing with this brilliant jsfiddle,其中 json使用knockout mapping plugin拉取然后映射。
var company;
function PersonViewModel(data) {
var personMapping = {
'ignore': ['twitter', 'webpage'],
'copy': ['age'],
'lastName': {
'create': function (options) {
return ko.observable(options.data.toUpperCase());
}
}
};
ko.mapping.fromJS(data, personMapping, this);
this.fullName = ko.computed(function () {
return this.firstName() + ' ' + this.lastName();
}, this);
}
function CompanyViewModel(data) {
var companyMapping = {
'ignore': ['address', 'website'],
'name': {
'create': function (options) {
return ko.observable(options.data.toUpperCase());
}
},
'employees': {
key: function (data) {
return ko.utils.unwrapObservable(data.personId);
},
create: function (options) {
return new PersonViewModel(options.data);
}
}
};
ko.mapping.fromJS(data, companyMapping, this);
}
我不知道如何实现的是 如何以及在何处 准确地添加 'addEmployee' 和 'removeEmployee' 函数?以及如何将它们绑定到按钮?
提前致谢!
您可以将这些函数添加到您的 CompanyViewModel
。
CompanyViewModel
...
this.addEmployee = function () {
this.employees.push(new PersonViewModel({
firstName: 'New',
lastName: 'Employee',
age: 777,
}));
};
this.removeEmployee = function () {
this.employees.pop();
};
HTML
....
<div data-bind="click: addEmployee">Add Employee</div>
<div data-bind="click: removeEmployee">Remove Employee</div>
...
添加这些内容的合理位置是您的 CompanyViewModel
。例如,像这样:
function CompanyViewModel(data) {
var self = this;
var companyMapping = {
// ...as before
};
self.addEmployee = function () {
// as an example, we are just adding a static new employee
self.employees.push(new PersonViewModel({
lastName: "new",
firstName: "employee",
age: 10
}));
}
// important, with how we are binding the function, we expect the
// argument, e, to be the employee to remove
self.removeEmployee = function (e) {
self.employees.remove(e);
}
ko.mapping.fromJS(data, companyMapping, this);
}
添加绑定,可以这样操作:
<div id="company">
<h1 data-bind="text: name"></h1>
<h2>Employees</h2>
<input type="button" value="add" data-bind="click: addEmployee" />
<table>
<thead>
<tr>
<th>Full name</th>
<th>Last name</th>
<th>First name</th>
<th>Age</th>
</tr>
</thead>
<tbody data-bind="foreach: employees">
<tr>
<td data-bind="text: fullName"></td>
<td data-bind="text: lastName"></td>
<td data-bind="text: firstName"></td>
<td data-bind="text: age"></td>
<td>
<input type="button" value="x" data-bind="click: $parent.removeEmployee" />
</td>
</tr>
</tbody>
</table>
</div>
这将为每个员工添加一个 add
按钮以及一个删除 x
按钮,该按钮调用父 CompanyViewModel
传递的 removeEmployee
函数员工。
这是更新后的 fiddle