Looking for some help with KnockoutJS and an MVC application I am working on.
I am attempting to use Knockoutjs to map a server side View Model to a Client side View Model then via the view add each client view model to a collection and (not in the below code) return back to the controller using AJAX.
Up to now when I attempt to add a View Model to the knockout array I receive the following error :
TrainingCourse.js:47 Uncaught TypeError: Cannot read property 'fromJS' of undefined
My knockout script is as follows :
TrainingCourseViewModel = function(data) {
var self = this;
jsonData = data;
self.rows = ko.observableArray([
new TrainingCourseItemViewModel({
"TrainLevel": 1, "TrainCourseTitle": null, "TrainProviderName": null, "TrainDateStarted": null,
"TrainDateCompleted": null, "TrainHoursAttended": 0, "TrainCost": 0, "QualificationGained": false,
"VoluntDateStarted": null, "VoluntDateEnded": null, "VoluntWhoWith": null, "VoluntHoursAttended": 0, "VoluntContactDetails": null,
"WorkExpDateStarted": null, "WorkExpDateEnded": null, "WorkExpWhoWith": null, "WorkExpHoursAttended": 0, "WorkExpContactDetailsEmployer": null,
"DateofPurchase": null, "Cost": 0, "PurchaseDetails": null, "PersonId": 0
})
]);
self.addRow = function () {
self.rows.push(new TrainingCourseItemViewModel({
"TrainLevel": 0, "TrainCourseTitle": null, "TrainProviderName": null, "TrainDateStarted": null,
"TrainDateCompleted": null, "TrainHoursAttended": 0, "TrainCost": 0, "QualificationGained": false,
"VoluntDateStarted": null, "VoluntDateEnded": null, "VoluntWhoWith": null, "VoluntHoursAttended": 0, "VoluntContactDetails": null,
"WorkExpDateStarted": null, "WorkExpDateEnded": null, "WorkExpWhoWith": null, "WorkExpHoursAttended": 0, "WorkExpContactDetailsEmployer": null,
"DateofPurchase": null, "Cost": 0, "PurchaseDetails": null, "PersonId": 0}));
}
self.removeRow = function (row) {
self.rows.remove(row);
calculateTrainingCost();
calculateOverallTotal();
trainingDateAutoCompleted();
}
function TrainingCourseItemViewModel() {
var self = this;
ko.mapping.fromJS(data, {}, self);
}
}
The error is occurring at line 47 of that file which is the following :
function TrainingCourseItemViewModel() {
var self = this;
ko.mapping.fromJS(data, {}, self);
}
The associated view is as follows :
@* Serialize model in to JSON *@
@{ string data = new JavaScriptSerializer().Serialize(Model);}
<h3>Add Training/Qualification</h3>
<div id="TrainingCourseViewModel">
<table class="table table-hover">
<thead>
<tr>
<th>CQFW Level</th>
<th>Course Title</th>
<th>Provider Name</th>
<th>Date Started</th>
<th>Date Completed</th>
<th>Hours Attended</th>
<th>Cost</th>
<th>Qualification Gained?</th>
</tr>
</thead>
<tbody data-bind="foreach: rows" id="trainingPadding">
<tr>
<td class="col-md-1">@Html.EnumDropDownListFor(modelItem => Model.TrainLevel, new { @class = "form-control site-level-ddl trainingLevel", data_bind = "value: TrainLevel" })</td>
<td class="col-md-2"><input type="text" data-bind="value: TrainCourseTitle" class="form-control" /></td>
<td class="col-md-2"><input type="text" data-bind="value: TrainProviderName" class="form-control" /></td>
<td class="col-md-1"><input type="text" data-bind="value: TrainDateStarted" class="form-control date-input datepicker" placeholder="dd/mm/yyyy" /></td>
<td class="col-md-1"><input type="text" data-bind="value: TrainDateCompleted" class="form-control date-input datepicker trainingDateCompleted hasDatepicker" onchange="trainingDateAutoCompleted()" placeholder="dd/mm/yyyy" /></td>
<td class="col-md-1"><input type="text" data-bind="value: TrainHoursAttended" class="form-control" onkeyup="calculateTrainingCost()" /></td>
<td class="col-md-1"><input type="text" data-bind="value: TrainCost" class="form-control trainingCost" placeholder="£0.00" onkeyup="calculateTrainingCost(), calculateOverallTotal()" /></td>
<td class="col-md-1" style="text-align: center"><input type="checkbox" data-bind="value: QualificationGained" class="" /></td>
<td class="col-md-1" style="width: 4%; text-align: center"><a href="#" data-bind="click: $root.removeRow" class="glyphicon glyphicon-trash text-danger" /></td>
</tr>
</tbody>
</table>
<input type="button" value="Add" data-bind="click: addRow" class="btn btn-default" />
</div>
<!---Scripts-->
<script type="text/javascript" src="~/Scripts/knockout-3.4.2.js"></script>
<script type="text/javascript" src="~/Scripts/knockout.mapping-latest.js"></script>
<script type="text/javascript" src="~/Scripts/KnockoutViewModels/TrainingCourse.js"></script>
<script type="text/javascript">
var trainingCourseViewModel = new TrainingCourseViewModel(@Html.Raw(data));
ko.applyBindings(trainingCourseViewModel);
</script>
Any help or suggestion would be greatly appreciated as I am pretty new to KnockoutJS...
Cheers
Make sure the dom us fully loaded when you are creating view model instance and initiating the bindings.
If pure java script, use,
window.addEventListener('DOMContentLoaded', function(){
var trainingCourseViewModel = new TrainingCourseViewModel(@Html.Raw(data));
ko.applyBindings(trainingCourseViewModel);
});
OR if you are using the jQuery framework,
$(function(){
var trainingCourseViewModel = new TrainingCourseViewModel(@Html.Raw(data));
ko.applyBindings(trainingCourseViewModel);
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.