Reputation:
How do you create a KO.JS ViewModel in an external JS file then use it in an html file? This seems like such a simple thing but I cannot get it to work and cannot find any clear information on how to do this. If I have overlooked I apologize and will remove this if someone can point me to the answer.
EXTERNAL vm:
var myApp = (function (myApp) {
myApp.ReportViewModel = function() {
var self = this;
self.test = ko.observable();
}
}(myApp || {}));
Seperate HTML File:
<!DOCTYPE html>
<html>
<head><title>My Page</title></head>
<body>
<table>
<tr>
<td>First Name</td>
<td><input type="text" data-bind='value: test'/></td>
</tr>
</table>
<h2>Hello, <span data-bind="text: test"> </span>!</h2>
<!-- reference this *before* initializing -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"> </script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
<script src="myApp.js"></script>
<!-- fire off your app -->
<script>
($function(){
var reportVM = new myApp.ReportViewModel();
ko.applyBindings(reportVM);
});
</script>
EDIT I have made the suggested changes. This is what my project now looks like but it is still not working. Also the knockout.js code is not running at all.
Upvotes: 4
Views: 7303
Reputation: 63739
You're on the right path. As @nemesv comments you may need to reference the external JS before you can use it. In addition, I'd recommend creating a namespace object for your app. All this together would look like this:
<html>
<head><title>My Page</title></head>
<body>
<table>
<tr>
<td>First Name</td>
<td><input type="text" data-bind='value: test'/></td>
</tr>
</table>
<h2>Hello, <span data-bind="text: test"> </span>!</h2>
<!-- reference this first -->
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<!-- reference this *before* initializing -->
<script src="myApp.js"></script>
<!-- fire off your app -->
<script>
$(function(){
var reportVM = new myApp.ReportViewModel();
ko.applyBindings(reportVM);
});
</script>
</body>
</html>
PS. Note that I changed new reportVM
to just reportVM
in the second line. It's just a var at that point, no need to "new" it. In addition, I've fixed the parentheses placement on that bit of script.
And in myApp.js
have this:
var myApp = (function (myApp) {
myApp.ReportViewModel = function() {
var self = this;
self.test = ko.observable("Testing 123");
}
return myApp;
}(myApp || {}));
This way things like ReportViewModel
and other constructor functions for your app won't linger in the global namespace, but will be part of the myApp
object ("namespace", if you will).
Upvotes: 3