Originally posted on: http://geekswithblogs.net/Aligned/archive/2013/07/17/knockout-with-prototype-and-inheritance.aspx
I’m refactoring code to use a prototypal inheritance instead of the Revealing Module Pattern. I’m using TypeScript for inheritance, seeing what it kicks out and copying and modifying that (that’d be worth a blog post). There were a few modifications that I needed to make.
Subscribe and Computed need a different approach. See http://stackoverflow.com/questions/14120507/using-prototype-for-knockoutjs-computed-properties. This code snippet is from Anders.
ViewModel = function() {this.fullName = ko.computed(this.getFullName, this); }; ViewModel.prototype = { getFullName: function() { returnthis.firstName() + " " + this.lastName(); } };
A sample of a view model after the refactor:
TestVm = (function (_super) {"use strict"; __extends(TestVm, _super); TestVM = function (){// constructor// setup properties for bindingthis.Title = ko.observable('Hello!');this.Movies = ko.observableArray();this.SelectedMovie = ko.observable();// handle observable subscribesthis.SelectedMovie.subscribe(this.subscribeSelectedMovie, this);// handle computedthis.NewestMovie = ko.computed(this.computedNewestMovie, this); }// methods TestVM.prototype.Init = function(){// have to use call to send this as the context. _super.Init.call(this);// save self, so it can be used inside the complete var self = this; dataService.AdministrationDataService.GetMovies() .done(function (results) {// watch out 'this' is no longer 'this'! self.Movies(results); }); }; TestVm.prototype.subscribeSelectedMovie = function (movie) { toastr.info(movie.Name + " selected"); }; TestVm.prototype.computedNewestMovie = function (){// add real code to find the newest moviereturnthis.Movies()[0]; }; }(ParentVm));