{"id":19,"date":"2011-08-21T16:40:05","date_gmt":"2011-08-21T16:40:05","guid":{"rendered":"http:\/\/adam.finzel.co.uk\/?p=19"},"modified":"2011-08-21T18:22:06","modified_gmt":"2011-08-21T18:22:06","slug":"first-open-source-project-knockout-creator","status":"publish","type":"post","link":"http:\/\/adam.finzel.co.uk\/?p=19","title":{"rendered":"First Open Source Project &#8211; Knockout Creator"},"content":{"rendered":"<p>Well it looks like this blog is all about firsts at the moment.  Today I created my first open source project, Knockout Creator.  This is a library that supports Knockout.Js.<\/p>\n<p><strong>What is Knockout.js?<\/strong><\/p>\n<p>Knockout.js can be found at <a href=\"http:\/\/knockoutjs.com\/\" title=\"http:\/\/knockoutjs.com\/\" target=\"_blank\">http:\/\/knockoutjs.com\/<\/a> .  Knockout is a Javascript library that brings a MVC approach to Javascript.  The idea is that you create a view model in javascript.  You can then change the UI dependent on the view model.  Its probably easier to understand if you look at a live demo <a href=\"http:\/\/knockoutjs.com\/examples\/twitter.html\" title=\"http:\/\/knockoutjs.com\/examples\/twitter.html\" target=\"_blank\">http:\/\/knockoutjs.com\/examples\/twitter.html<\/a>.<\/p>\n<p><strong>So whats your project do?<\/strong><br \/>\nThe problem I found with knockout is, you end up creating the view model in Javascript and then recreate the same model in c# when you want top pass the view model back to c# for saving or lookup.  I hate duplicate code!! So Knockout Creator will generate the Javascript view model for you so the view model exists in just one place.<\/p>\n<p><strong>Usage<\/strong><\/p>\n<p><strong>Your View Model<\/strong><\/p>\n<pre class=\"brush: c#; title: ; notranslate\" title=\"\">\r\nnamespace knockoutExample\r\n{\r\n\tpublic class Restaurant : Knockout.ViewModel\r\n\t{\r\n\t        public int RestaurantId { get; set; }\r\n\t\tpublic string Name { get; set; }\r\n\r\n\t}\r\n}\r\n<\/pre>\n<p><strong>Setting up your controller<\/strong><\/p>\n<pre class=\"brush: c#; title: ; notranslate\" title=\"\">\r\npublic string KnockOutJs() {\r\n\trestViewModel = new Restaurant();\r\n\tkoCreator = new Knockout.KoCreator()\r\n\r\n\t\/\/Set your controller name\r\n\tkoCreator.PageName = \"Home\";\r\n\r\n\t\/\/Add your viewmodel Restaurant is the name of the model we want in javascript\r\n\tkoCreator.AddViewModel(\"Restaurant\", restViewModel.GetType());\r\n\r\n\t\/\/Add a javascript function subscription.  This will call the javascript function test() everytime the name is changed\r\n\tkoCreator.AddJsSubscription(\"Name\",\"test\");\r\n\r\n\t\/\/This will return the javascript, we pass in the controller so that Knockout Creator can bind subscriptions\r\n\treturn koCreator.GenerateJs(this);\r\n}\r\n\r\n<\/pre>\n<p><strong>Creating a method to be called using AJAX<\/strong><\/p>\n<pre class=\"brush: c#; title: ; notranslate\" title=\"\">\r\n\/\/Add a custom attribute specifying the variable that when changed will trigger this via AJAX\r\n[KoMethod(\"RestaurantId\")]\r\n\r\n\/\/The method accepts one attribute, our viewmodel.  This will be passed back using AJAX\r\npublic JsonResult GetRestaurantById(knockoutExample.Restaurant viewModel) {\r\n\r\n\t\/\/get the restaurantId that has been posted\r\n\tint restaurantId = viewModel.RestaurantId;\r\n\r\n\t\/\/Load the record from the db\r\n\tRestaurant restaurant = _restaurantRepository.Load(restaurantId);\r\n\r\n\t\/\/ set the viewmodel name\r\n        viewModel.Name = restaurant.Name\r\n\t\r\n\t\/\/return the viewmodel back to the browser\r\n\treturn Json(viewModel);\r\n}\r\n<\/pre>\n<p><strong>Setting up your view<\/strong><\/p>\n<pre class=\"brush: c#; title: ; notranslate\" title=\"\">\r\n<script type=\"text\/javascript\" language=\"javascript\">\r\n\t@Html.Action(\"KnockOutJs\",\"Home\")\r\n<\/script>\r\n<\/pre>\n<p><strong>What gets put in your browser?<\/strong><\/p>\n<pre class=\"brush: javascript; title: ; notranslate\" title=\"\">\r\n<script type=\"text\/javascript\" language=\"javascript\">\r\n$(function() {var baseModel = {RestaurantId: ko.observable(),\r\nName: ko.observable(),\r\n$(function() {var  Restaurant = ko.mapping.fromJS(baseModel);\r\nwindow.Restaurant = Restaurant;\r\nko.applyBindings(window.Restaurant);Restaurant.Name.subscribe(function(){test()});\r\n});\r\n});\r\n<\/script>\r\n<\/pre>\n<p><strong>So what now?<\/strong><\/p>\n<p>Every time the RestaurantId is updated a call will be made to the server and will run GetRestaurantById.  GetRestaurantId will load the Restaurant from the database and will return the view model back.<\/p>\n<p><strong>How can I get the source?<\/strong><br \/>\nGet over to github <a href=\"https:\/\/github.com\/afinzel\/KnockoutCreator\" title=\"https:\/\/github.com\/afinzel\/KnockoutCreator\" target=\"_blank\">https:\/\/github.com\/afinzel\/KnockoutCreator<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Well it looks like this blog is all about firsts at the moment. Today I created my first open source project, Knockout Creator. This is a library that supports Knockout.Js. What is Knockout.js? Knockout.js can be found at http:\/\/knockoutjs.com\/ . Knockout is a Javascript library that brings a MVC approach to Javascript. The idea is [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-19","post","type-post","status-publish","format-standard","hentry","category-c"],"_links":{"self":[{"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/19","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=19"}],"version-history":[{"count":11,"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/19\/revisions"}],"predecessor-version":[{"id":22,"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/19\/revisions\/22"}],"wp:attachment":[{"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=19"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=19"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/adam.finzel.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=19"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}