Knockout allows you to bind the HTML to your javascript object. It simplifies DOM manipulation and allow the portability of the javascript object and action. It is pretty much the same concept as MVVM in silverlight. You can wire up the function with button click easily, you can have for each against your array (e.g like repeater). It is so elegant, but debugging sometimes can be challenging as well. I’ve used Knockout along with JSON that allows me to build rich and interactive website
2 powerful function: ko.observable – this allow knockout to monitor this object value, ko.observableArray this is the extension of ko.observable against the array. With observable, knockout will keep tracking the value of that property and allow the DOM that has been bind against it to refresh
You can bind initial data from your MVC model to the variable in javascript and bind it, in this sample below, I use ToJson extension function
- namespace System.Web.Mvc
- {
- public static class HtmlHelperExtensions
- {
- ///<summary>
- /// Serializes an object to Javascript Object Notation.
- ///</summary>
- ///<param name=”item”>The item to serialize.</param>
- ///<returns>
- /// The item serialized as Json.
- ///</returns>
- public static string ToJson(this object item)
- {
- return new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(item);
- }
- }
- }
Sample code
- <script type=”text/javascript”>
- var initialData = @(new MvcHtmlString(Model.ToJson()));
- function JobResultViewModel()
- {
- var self = this;
- self.Jobs = ko.observableArray(initialData.JobSearchResults);
- self.Search = ko.observable(initialData.JobSearchModel);
- self.Pageno = ko.observable(initialData.PageNo);
- self.TotalPage = ko.observable(initialData.TotalPage);
- self.TotalRecord = initialData.TotalRecord;
- self.ShowNextButton = ko.computed(function(){
- return self.Pageno() < (self.TotalPage() – 1);
- });
- self.LoadNextPage = function() {
- $.getJSON(‘@Url.Action(“ResultJson”)‘, { Keyword: (self.Search().Keyword == null) ? “” : self.Search().Keyword,
- ProfessionId: self.Search().ProfessionId,
- RoleIds: self.Search().RoleId,
- SalaryTypeId: self.Search().SalaryTypeId,
- SalaryFromId: self.Search().SalaryFromId,
- SalaryToId: self.Search().SalaryToId,
- LocationId: self.Search().LocationId,
- AreaIds: (self.Search().AreaId.length == 0) ? 0 : self.Search().AreaId,
- WorkTypeId: self.Search().WorkTypeId,
- Pageno: self.Pageno() + 1
- }, function (SearchResult) {
- $.each(SearchResult, function(i, item)
- {
- self.Jobs.push(item);
- });
- self.Pageno(self.Pageno() + 1);
- //we need to refresh the repeater when we use jquery mobile ONLY
- $(“#JobRepeater”).listview(“refresh”);
- });
- }
- }
- ko.applyBindings(new JobResultViewModel());
- </script>
- <h2>Result</h2>
- <h1>There are <span data-bind=”text: TotalRecord”></span> jobs</h1>
- <a>Save Search</a>
- <ul name=”JobRepeater” id=”JobRepeater” data-role=”listview” data-bind=”foreach: Jobs”>
- <li><a data-bind=”attr: { href: UrlAction, title: JobName },text : JobName”></a><span data-bind=”text: Description”></span></li>
- </ul>
- <div data-bind=”visible: ShowNextButton”>
- <input type=”button” id=”btn_load_next” value=”Load More” data-bind=”click: LoadNextPage”/>
- </div>
Source:
Leave a Reply