knockout.js

时间:2018-04-11 01:39:53

标签: knockout.js

编辑:

我需要创建一个打印可观察数组对象属性行的表。

因此,每个作业都可以有一系列任务。我有输入框来向下拉菜单添加作业和任务,还有一个提交按钮,用于将所选任务添加到所选作业。一切正常。我已经检查过,任务被推送到各自的作业对象任务数组中。

编辑:我在控制台中检查viewModel.jobs()[0] .tasks(),它显示正确添加的任务。

然后我想使用嵌套模板(上图)

在表格中显示结果

编辑:我开始使用这种方法简单地在表中嵌套foreaches并假设父子层次结构可以工作。很明显,我的JavaScript中存在错误,但任务仍然没有显示出来,而且我已经陷入困境......非常感谢你们的帮助!



var job = function(name) {
  this.jobName = name;
  this.tasks = ko.observableArray();
}

var task = function(name) {
  this.taskName = name;
}

var viewModel = {
  selectedJob: ko.observable(),
  selectedTask: ko.observable(),
  jobName: "",
  jobs: ko.observableArray([new job("job1")]),
  taskName: "",
  taskList: ko.observableArray([new task("task1")]),

  addJob: function() {
    var objectToAdd = new job(this.jobName);

    if (objectToAdd.jobName === "") return;

    for (var i = 0; i < this.jobs().length; i++) {
      if (objectToAdd.jobName === this.jobs()[i].jobName) {

        return;
      }
    }
    this.jobs.push(objectToAdd);
  },

  addTask: function() {
    var taskToAdd = new task(this.taskName);

    if (taskToAdd.taskName === "") return;

    for (var i = 0; i < this.taskList().length; i++) {
      if (taskToAdd.taskName === this.taskList()[i].taskName) {

        return;
      }
    }

    this.taskList.push(taskToAdd);
  },

  removeJob: function(job) {
    viewModel.jobs.remove(job);
  },

  submitTask: function() {

    this.selectedJob().tasks().push(this.selectedTask());

  },

}

ko.applyBindings(viewModel);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form data-bind="submit: submitTask">
  <div class="form-element-container">
    <span>
      <select data-bind="options: jobs, optionsText: 'jobName', value: selectedJob, optionsCaption: 'Select Job'"></select>
      <input class="text-box" data-bind="value: jobName" /><button data-bind="click: addJob">Add Job</button>
    </span>
  </div>
  <div class="form-element-container">
    <span>
      <select data-bind="options: taskList, optionsText: 'taskName',
                         value: selectedTask, optionsCaption: 'Select Task'"></select>
      <input class="text-box" data-bind="value: taskName" /><button data-bind="click: addTask">Add Task</button>
    </span>
  </div>
  <div class="form-element-container">
    <button class="submit-button" data-bind="click: submitTask">Add to Timesheet</button>
  </div>
</form>
<div class="table-container">
  <h2>Timesheet:</h2>
  <table class="table">
    <tbody data-bind="foreach: jobs">
      <tr>
        <th>
          <span data-bind="text: jobName"></span>
        </th>
        <th>Hours</th>
      </tr>
      <tr data-bind="foreach: tasks">
        <td>
          <span data-bind="text: taskName"></span>
        </td>
      </tr>
    </tbody>
  </table>

</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

您无法将div直接放在table元素中。这就是它被忽略的原因。

将此<div data-bind="template: {name: 'tasksTemplate', foreach: tasks}"></div>更改为<tr>,并将模板修改为td

此部分也可能是拼写错误:<td data-bind="taskName"></td>

var job = function(name) {
    this.jobName = name;
    this.tasks = ko.observableArray([
      new task("job1"),
      new task("job2")
    ]);
}

var task = function(name) {
    this.taskName = name;
}

var VM = function(){
    this.jobs = [
      new job("Dev"),
      new job("Tester")
    ]
}

ko.applyBindings(new VM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<table class="table">
    <tbody data-bind="template: {name: 'jobsTemplate', foreach: jobs}">
    </tbody>
</table>

<script type="text/html" id="jobsTemplate">
    <tr>
        <th>
            <span data-bind="text: jobName"></span>
            <a class="badge badge-pill danger" data-bind="click: $root.removeJob">remove</a>
        </th> 
        <th>Hours</th>
    </tr>
    <tr data-bind="template: {name: 'tasksTemplate', foreach: tasks}"></tr>
</script>

<script type="text/html" id="tasksTemplate">
    <td data-bind="text: taskName"></td>
</script>

此外,您可能希望使用SO的代码段功能,以便您的代码可以运行。

答案 1 :(得分:0)

@Adrian建议的应该是什么。它也可以用更简单的代码来实现

var job = function(name) {
    this.jobName = name;
    this.tasks =[
      new task("job1"),
      new task("job2")
    ]
}

var task = function(name) {
    this.taskName = name;
}

var VM = function(){
    this.jobs = [
      new job("Dev"),
      new job("Tester")
    ]
}

ko.applyBindings(new VM());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<table class="table">
    <tbody data-bind="foreach: jobs">
        <tr>
          <th>
            <span data-bind="text: jobName"></span>            
          </th> 
          <th>Hours</th>                      
        </tr>  
       <tr data-bind="foreach: tasks">          
              <td >      
                  <span data-bind="text: taskName"></span>
              </td>          
       </tr>
    </tbody>
</table>