使用淘汰赛下降

时间:2015-04-07 01:48:40

标签: knockout.js

目前我正在制作一个非常基本的时间表。 所以我现在拥有的是一个按钮来点击添加员工,它为他们创造了一周。我想要发生的是员工姓名输入是一个下拉而不是我不知道如何继续下去,这是迄今为止我所拥有的 一个小提琴 http://jsfiddle.net/grahamwalsh/1p3nnkyg/

HTML

<div class='timesheet'> 

<form action='/someServerSideHandler'>
    <p>You have asked for <span data-bind='text: employees().length'>&nbsp;</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; }

1 个答案:

答案 0 :(得分:1)

如果我理解您的问题,您希望您的用户从员工列表中选择一个或多个人。你的方法有几个问题,我一直在努力纠正。

您将您的viewmodel命名为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();
};

出于本演示的目的,我将直接将它们提供给viewmodel:

var viewModel = new ViewModel([
    new Employee('Jane'),
    new Employee('John'),
    new Employee('Alice'),
    new Employee('Bob')
]);

我们基本上有两个列表 -

  1. 用户可以选择的员工列表,
  2. 用户选择的员工
  3. 所以我们需要两个observableArrays:

    var ViewModel = function ViewModel(employees) {
        this.availableEmployees = ko.observableArray(employees);
        this.selectedEmployees  = ko.observableArray([]);
    };
    

    我会更改用户界面并让用户先选择员工:

    enter image description here

    通过这种方式,我们可以使用仅包含尚未添加的员工的动态选择,从而允许我们阻止员工被添加两次。

    这是我们的<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创建选项,并使用每个name的{​​{1}}属性作为选项标签文本。如果没有,我们隐藏一切。

    Employee是另一个可观察对象,保留当前在employeeToBeAdded中选择的员工,当&#34;添加员工&#34;点击。

    如果发生这种情况,我们会从列表中选择所选员工,将其添加到<select>并将其从selectedEmployees中删除。对于availableEmployees,我们做相反的事情:

    removeEmployee

    以下是完整的,可运行的示例:

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