将对象推送到observableArray

时间:2017-11-13 17:52:51

标签: javascript knockout.js data-binding

敲门的新手,我正在关注Loading and saving data的教程,但我遇到了一些麻烦。当我将对象推送到数组时,数组为空。我也在使用表格。这是我的代码,

function Quiz(data) {
    this.quiz_name = ko.observable(data.newQuizName);
    this.quiz_type = ko.observable(data.newQuizType);
}


function QuizViewModel() {
    var self = this;
    self.quizzes = ko.observableArray([]);
    self.newQuizName = ko.observable();
    self.newQuizType = ko.observable();

    self.addQuiz = function () {
        self.quizzes.push(new Quiz({quiz_name: this.newQuizName(), quiz_type: this.newQuizType()}))
        console.log(ko.toJSON(self.quizzes));
    };
}

ko.applyBindings(new QuizViewModel());

这是我的HTML

 <form name="quizzes" id="new-form-quizzes" data-bind="submit: addQuiz" style="display:none">
    <div class="form-group">
        <label for="quiz-name">Quiz Name</label>
        <input type="text" class="form-control" id="quiz-name" aria-describedby="quiz name"
               data-bind="value: newQuizName"
               placeholder="Quize Name"/>
    </div>
    <div class="form-group">
        <label for="quiz-type">Quiz Type</label>
        <input type="text"
               class="form-control"
               id="quiz-type"
               data-bind="value: newQuizType"
               placeholder="Quiz Type"/>
    </div>
    <button type="submit">Save</button>
</form>

由于newQuizNamenewQuizType都有值,因此不确定我做错了什么。任何帮助将非常感激。

1 个答案:

答案 0 :(得分:1)

您应该将包含observables的对象(或数组)作为参数传递给ko.toJSON。不是观察本身。因此,您需要将代码更改为:

ko.toJSON(self.quizzes());

ko.toJSON internally calls ko.toJS。后一种方法遍历对象并将每个observable转换为该observable的值。

进行此更改后,您会发现还有其他问题。新添加的Quiz对象具有undefined个属性。这是因为您将quiz_namequiz_type的对象传递给Quiz构造函数。但是您正在从newQuizName参数访问data属性。所以将代码更改为:

&#13;
&#13;
function Quiz(data) {
  this.quiz_name = ko.observable(data.quiz_name); // these 2 props must be changed
  this.quiz_type = ko.observable(data.quiz_type);
}


function QuizViewModel() {
  var self = this;
  self.quizzes = ko.observableArray([]);
  self.newQuizName = ko.observable();
  self.newQuizType = ko.observable();

  self.addQuiz = function() {
    self.quizzes.push(new Quiz({
      quiz_name: this.newQuizName(),
      quiz_type: this.newQuizType()
    }));

    console.log(ko.toJSON(self.quizzes()));
  };
}

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

<form name="quizzes" id="new-form-quizzes" data-bind="submit: addQuiz">
  <div class="form-group">
    <label for="quiz-name">Quiz Name</label>
    <input type="text" class="form-control" id="quiz-name" aria-describedby="quiz name" data-bind="value: newQuizName" placeholder="Quize Name" />
  </div>
  <div class="form-group">
    <label for="quiz-type">Quiz Type</label>
    <input type="text" class="form-control" id="quiz-type" data-bind="value: newQuizType" placeholder="Quiz Type" />
  </div>
  <button type="submit">Save</button>
</form>

<!--Table to display the added quizzes-->
<table data-bind="if: quizzes() && quizzes().length > 0">
  <thead>
    <th>Quiz Name</th>
    <th>Quiz Type </th>
  </thead>
  <tbody data-bind="foreach: quizzes">
    <tr>
      <td data-bind="text:quiz_name"></td>
      <td data-bind="text:quiz_type"></td>
    </tr>
  </tbody>
</table>
&#13;
&#13;
&#13;