使用击倒下拉
Drop down using knockout
目前我正在制作一个非常基本的时间表。
所以我目前拥有的是一个点击添加员工的按钮,它会为他们生成一个星期。我想要发生的是员工姓名输入是一个下拉列表,但我不确定如何继续,这是我到目前为止所拥有的
一个 fiddle
http://jsfiddle.net/grahamwalsh/1p3nnkyg/
HTML
<div class='timesheet'>
<form action='/someServerSideHandler'>
<p>You have asked for <span data-bind='text: employees().length'> </span> employee(s)</p>
<table data-bind='visible: employees().length > 0'>
<thead>
<tr>
<th>Employee Name</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: employees'>
<tr>
<td><input class='required' data-bind='value: name, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: hours, uniqueName: true' /></td>
删除
<button data-bind='click: addEmployee'>Add Employee</button>
<button data-bind='enable: employees().length > 0' type='submit'>Submit</button>
</form>
淘汰赛
var EmployeeModel = function(employees) {
var self = this;
self.employees = ko.observableArray(employees);
self.addEmployee = function() {
self.employees.push({
Name: "",
Monday: "",
Tuesday:"",
Wednesday:"",
Thursday:"",
Friday:"",
Saturday:"",
Sunday:""
});
};
self.removeEmployee = function(employee) {
self.employees.remove(employee);
};
self.save = function(form) {
alert("Could now transmit to server: " + ko.utils.stringifyJson(self.employees));
};
};
var viewModel = new EmployeeModel([
]);
ko.applyBindings(viewModel);
$("form").validate({ submitHandler: viewModel.save });
body { font-family: arial; font-size: 14px; }
.timesheet { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.timesheet input { font-family: Arial; }
.timesheet b { font-weight: bold; }
.timesheet p { margin-top: 0.9em; margin-bottom: 0.9em; }
.timesheet select[multiple] { width: 100%; height: 8em; }
.timesheet h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; }
.timesheet table, .liveExample td, .liveExample th { padding: 0.2em; border-width: 0; }
.timesheet td input { width: 13em; }
tr { vertical-align: top; }
.timesheet input.error { border: 1px solid red; background-color: #FDC; }
.timesheet label.error { display: block; color: Red; font-size: 0.8em; }
.timesheet th { font-weight: bold; }
li { list-style-type: disc; margin-left: 20px; }
如果我对你的问题的理解正确,你希望你的用户从员工列表中选择一个或多个人。你的方法有几个问题,我正在努力纠正这些问题。
您将视图模型命名为 EmployeeModel
,但您基本上还有另一个针对员工的临时数据模型:
self.employees.push({
Name: "",
Monday: "",
Tuesday:"",
Wednesday:"",
Thursday:"",
Friday:"",
Saturday:"",
Sunday:""
});
顺便说一句,这是行不通的,因为您忘记了使属性成为可观察对象。如果将Name
绑定到一个输入字段值,例如<input data-bind="value: Name">
,它只会将输入设置为Name
的初始内容一次。之后,无论您更改可观察的 Name
还是 <input>
值,都不会再发生任何事情。
所以让我们将您的视图模型重命名为 ViewModel
并为 Employee
创建一个专用数据模型:
var Employee = function Employee(name) {
this.name = ko.observable(name);
this.monday = ko.observable();
this.tuesday = ko.observable();
this.wednesday = ko.observable();
this.thursday = ko.observable();
this.friday = ko.observable();
this.saturday = ko.observable();
this.sunday = ko.observable();
};
出于本演示的目的,我会将它们直接输入到视图模型中:
var viewModel = new ViewModel([
new Employee('Jane'),
new Employee('John'),
new Employee('Alice'),
new Employee('Bob')
]);
我们基本上有两个列表 —
- 用户可以选择的员工列表,以及
- 用户select编
的员工
所以我们需要两个 observableArrays:
var ViewModel = function ViewModel(employees) {
this.availableEmployees = ko.observableArray(employees);
this.selectedEmployees = ko.observableArray([]);
};
我会更改用户界面,让用户 select 首先成为员工:
这样,我们可以使用仅包含尚未添加的员工的动态 select,从而防止员工被添加两次。
这是我们的 <select>
:
<!-- ko if: availableEmployees().length > 0 -->
<select data-bind="value: employeeToBeAdded,
options: availableEmployees,
optionsText: 'name'">
</select>
<button data-bind='click: addEmployee'>Add Employee</button>
<!-- /ko -->
我们从所有 availableEmployees
创建选项,并使用每个 Employee
的 name
属性 作为选项标签文本。如果 none 可用,我们将隐藏所有内容。
employeeToBeAdded
是另一个 observable,包含当前 selected 在 <select>
中的员工,单击 "Add Employee" 时将添加该员工。
发生这种情况时,我们从列表中获取 selected 员工,将其添加到 selectedEmployees
并从 availableEmployees
中删除。对于removeEmployee
,我们做相反的事情:
var ViewModel = function ViewModel(employees) {
var self = this;
this.availableEmployees = ko.observableArray(employees);
this.selectedEmployees = ko.observableArray([]);
this.employeeToBeAdded = ko.observable();
this.addEmployee = function addEmployee() {
var employee = self.employeeToBeAdded();
self.employeeToBeAdded(null);
self.selectedEmployees.push( employee );
self.availableEmployees.remove( employee );
};
this.removeEmployee = function removeEmployee(employee) {
self.availableEmployees.push(employee);
self.selectedEmployees.remove(employee);
};
};
这是完整的可运行示例:
var Employee = function Employee(name) {
this.name = ko.observable(name);
this.monday = ko.observable();
this.tuesday = ko.observable();
this.wednesday = ko.observable();
this.thursday = ko.observable();
this.friday = ko.observable();
this.saturday = ko.observable();
this.sunday = ko.observable();
};
var ViewModel = function ViewModel(employees) {
var self = this;
this.availableEmployees = ko.observableArray(employees);
this.selectedEmployees = ko.observableArray([]);
this.employeeToBeAdded = ko.observable();
this.addEmployee = function() {
var employee = self.employeeToBeAdded();
self.employeeToBeAdded(null);
self.selectedEmployees.push(employee);
self.availableEmployees.remove(employee);
};
self.removeEmployee = function(employee) {
self.availableEmployees.push(employee);
self.selectedEmployees.remove(employee);
};
self.save = function(form) {
alert("Could now transmit to server: " + ko.utils.stringifyJson(self.employees));
};
};
var viewModel = new ViewModel([
new Employee('Jane'),
new Employee('John'),
new Employee('Alice'),
new Employee('Bob')
]);
ko.applyBindings(viewModel);
body { font-family: arial; font-size: 14px; }
.timesheet { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.timesheet input { font-family: Arial; }
.timesheet b { font-weight: bold; }
.timesheet p { margin-top: 0.9em; margin-bottom: 0.9em; }
.timesheet select[multiple] { width: 100%; height: 8em; }
.timesheet h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; }
.timesheet table, .liveExample td, .liveExample th { padding: 0.2em; border-width: 0; }
.timesheet td input { width: 5em; }
tr { vertical-align: top; }
.timesheet input.error { border: 1px solid red; background-color: #FDC; }
.timesheet label.error { display: block; color: Red; font-size: 0.8em; }
.timesheet th { font-weight: bold; }
li { list-style-type: disc; margin-left: 20px; }
.debugging-output { padding: 2rem; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class='timesheet'>
<form action='/someServerSideHandler'>
<p>You have asked for <span data-bind='text: selectedEmployees().length'> </span> employee(s)</p>
<table data-bind='visible: selectedEmployees().length > 0'>
<thead>
<tr>
<th>Employee Name</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: selectedEmployees'>
<tr>
<td data-bind="text: name"></td>
<td><input class='required number' data-bind='value: monday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: tuesday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: wednesday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: thursday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: friday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: saturday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: sunday, uniqueName: true' /></td>
<td><button data-bind='click: $parent.removeEmployee'>Delete</button></td>
</tr>
</tbody>
</table>
<!-- ko if: availableEmployees().length > 0 -->
<select data-bind="value: employeeToBeAdded, options: availableEmployees, optionsText: 'name'"></select>
<button data-bind='click: addEmployee'>Add Employee</button>
<!-- /ko -->
<button data-bind='enable: selectedEmployees().length > 0' type='submit'>Submit</button>
</form>
</div>
<ul class="debugging-output" data-bind="foreach: selectedEmployees">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>
目前我正在制作一个非常基本的时间表。 所以我目前拥有的是一个点击添加员工的按钮,它会为他们生成一个星期。我想要发生的是员工姓名输入是一个下拉列表,但我不确定如何继续,这是我到目前为止所拥有的 一个 fiddle http://jsfiddle.net/grahamwalsh/1p3nnkyg/
HTML
<div class='timesheet'>
<form action='/someServerSideHandler'>
<p>You have asked for <span data-bind='text: employees().length'> </span> employee(s)</p>
<table data-bind='visible: employees().length > 0'>
<thead>
<tr>
<th>Employee Name</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: employees'>
<tr>
<td><input class='required' data-bind='value: name, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: hours, uniqueName: true' /></td>
删除
<button data-bind='click: addEmployee'>Add Employee</button>
<button data-bind='enable: employees().length > 0' type='submit'>Submit</button>
</form>
淘汰赛
var EmployeeModel = function(employees) {
var self = this;
self.employees = ko.observableArray(employees);
self.addEmployee = function() {
self.employees.push({
Name: "",
Monday: "",
Tuesday:"",
Wednesday:"",
Thursday:"",
Friday:"",
Saturday:"",
Sunday:""
});
};
self.removeEmployee = function(employee) {
self.employees.remove(employee);
};
self.save = function(form) {
alert("Could now transmit to server: " + ko.utils.stringifyJson(self.employees));
};
};
var viewModel = new EmployeeModel([
]);
ko.applyBindings(viewModel);
$("form").validate({ submitHandler: viewModel.save });
body { font-family: arial; font-size: 14px; }
.timesheet { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.timesheet input { font-family: Arial; }
.timesheet b { font-weight: bold; }
.timesheet p { margin-top: 0.9em; margin-bottom: 0.9em; }
.timesheet select[multiple] { width: 100%; height: 8em; }
.timesheet h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; }
.timesheet table, .liveExample td, .liveExample th { padding: 0.2em; border-width: 0; }
.timesheet td input { width: 13em; }
tr { vertical-align: top; }
.timesheet input.error { border: 1px solid red; background-color: #FDC; }
.timesheet label.error { display: block; color: Red; font-size: 0.8em; }
.timesheet th { font-weight: bold; }
li { list-style-type: disc; margin-left: 20px; }
如果我对你的问题的理解正确,你希望你的用户从员工列表中选择一个或多个人。你的方法有几个问题,我正在努力纠正这些问题。
您将视图模型命名为 EmployeeModel
,但您基本上还有另一个针对员工的临时数据模型:
self.employees.push({
Name: "",
Monday: "",
Tuesday:"",
Wednesday:"",
Thursday:"",
Friday:"",
Saturday:"",
Sunday:""
});
顺便说一句,这是行不通的,因为您忘记了使属性成为可观察对象。如果将Name
绑定到一个输入字段值,例如<input data-bind="value: Name">
,它只会将输入设置为Name
的初始内容一次。之后,无论您更改可观察的 Name
还是 <input>
值,都不会再发生任何事情。
所以让我们将您的视图模型重命名为 ViewModel
并为 Employee
创建一个专用数据模型:
var Employee = function Employee(name) {
this.name = ko.observable(name);
this.monday = ko.observable();
this.tuesday = ko.observable();
this.wednesday = ko.observable();
this.thursday = ko.observable();
this.friday = ko.observable();
this.saturday = ko.observable();
this.sunday = ko.observable();
};
出于本演示的目的,我会将它们直接输入到视图模型中:
var viewModel = new ViewModel([
new Employee('Jane'),
new Employee('John'),
new Employee('Alice'),
new Employee('Bob')
]);
我们基本上有两个列表 —
- 用户可以选择的员工列表,以及
- 用户select编 的员工
所以我们需要两个 observableArrays:
var ViewModel = function ViewModel(employees) {
this.availableEmployees = ko.observableArray(employees);
this.selectedEmployees = ko.observableArray([]);
};
我会更改用户界面,让用户 select 首先成为员工:
这样,我们可以使用仅包含尚未添加的员工的动态 select,从而防止员工被添加两次。
这是我们的 <select>
:
<!-- ko if: availableEmployees().length > 0 -->
<select data-bind="value: employeeToBeAdded,
options: availableEmployees,
optionsText: 'name'">
</select>
<button data-bind='click: addEmployee'>Add Employee</button>
<!-- /ko -->
我们从所有 availableEmployees
创建选项,并使用每个 Employee
的 name
属性 作为选项标签文本。如果 none 可用,我们将隐藏所有内容。
employeeToBeAdded
是另一个 observable,包含当前 selected 在 <select>
中的员工,单击 "Add Employee" 时将添加该员工。
发生这种情况时,我们从列表中获取 selected 员工,将其添加到 selectedEmployees
并从 availableEmployees
中删除。对于removeEmployee
,我们做相反的事情:
var ViewModel = function ViewModel(employees) {
var self = this;
this.availableEmployees = ko.observableArray(employees);
this.selectedEmployees = ko.observableArray([]);
this.employeeToBeAdded = ko.observable();
this.addEmployee = function addEmployee() {
var employee = self.employeeToBeAdded();
self.employeeToBeAdded(null);
self.selectedEmployees.push( employee );
self.availableEmployees.remove( employee );
};
this.removeEmployee = function removeEmployee(employee) {
self.availableEmployees.push(employee);
self.selectedEmployees.remove(employee);
};
};
这是完整的可运行示例:
var Employee = function Employee(name) {
this.name = ko.observable(name);
this.monday = ko.observable();
this.tuesday = ko.observable();
this.wednesday = ko.observable();
this.thursday = ko.observable();
this.friday = ko.observable();
this.saturday = ko.observable();
this.sunday = ko.observable();
};
var ViewModel = function ViewModel(employees) {
var self = this;
this.availableEmployees = ko.observableArray(employees);
this.selectedEmployees = ko.observableArray([]);
this.employeeToBeAdded = ko.observable();
this.addEmployee = function() {
var employee = self.employeeToBeAdded();
self.employeeToBeAdded(null);
self.selectedEmployees.push(employee);
self.availableEmployees.remove(employee);
};
self.removeEmployee = function(employee) {
self.availableEmployees.push(employee);
self.selectedEmployees.remove(employee);
};
self.save = function(form) {
alert("Could now transmit to server: " + ko.utils.stringifyJson(self.employees));
};
};
var viewModel = new ViewModel([
new Employee('Jane'),
new Employee('John'),
new Employee('Alice'),
new Employee('Bob')
]);
ko.applyBindings(viewModel);
body { font-family: arial; font-size: 14px; }
.timesheet { padding: 1em; background-color: #EEEEDD; border: 1px solid #CCC; max-width: 655px; }
.timesheet input { font-family: Arial; }
.timesheet b { font-weight: bold; }
.timesheet p { margin-top: 0.9em; margin-bottom: 0.9em; }
.timesheet select[multiple] { width: 100%; height: 8em; }
.timesheet h2 { margin-top: 0.4em; font-weight: bold; font-size: 1.2em; }
.timesheet table, .liveExample td, .liveExample th { padding: 0.2em; border-width: 0; }
.timesheet td input { width: 5em; }
tr { vertical-align: top; }
.timesheet input.error { border: 1px solid red; background-color: #FDC; }
.timesheet label.error { display: block; color: Red; font-size: 0.8em; }
.timesheet th { font-weight: bold; }
li { list-style-type: disc; margin-left: 20px; }
.debugging-output { padding: 2rem; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div class='timesheet'>
<form action='/someServerSideHandler'>
<p>You have asked for <span data-bind='text: selectedEmployees().length'> </span> employee(s)</p>
<table data-bind='visible: selectedEmployees().length > 0'>
<thead>
<tr>
<th>Employee Name</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: selectedEmployees'>
<tr>
<td data-bind="text: name"></td>
<td><input class='required number' data-bind='value: monday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: tuesday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: wednesday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: thursday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: friday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: saturday, uniqueName: true' /></td>
<td><input class='required number' data-bind='value: sunday, uniqueName: true' /></td>
<td><button data-bind='click: $parent.removeEmployee'>Delete</button></td>
</tr>
</tbody>
</table>
<!-- ko if: availableEmployees().length > 0 -->
<select data-bind="value: employeeToBeAdded, options: availableEmployees, optionsText: 'name'"></select>
<button data-bind='click: addEmployee'>Add Employee</button>
<!-- /ko -->
<button data-bind='enable: selectedEmployees().length > 0' type='submit'>Submit</button>
</form>
</div>
<ul class="debugging-output" data-bind="foreach: selectedEmployees">
<li data-bind="text: ko.toJSON($data)"></li>
</ul>