Site Loading

I have started a new job recently and one of the frameworks I have had to learn is knockout JS. This post is the result of all I have learned from some really smart people.

MVVM Pattern

Model: The model stores all the data associated with the application but do not have any behavior.  The data can be anything eg. User details etc.  The data is independent of the UI.

View:  The view is part of the application that the users interact with.  The view shows information that is controlled by the View Model but has know knowledge of the model or the View Model.

View Model:  The View Model controls what View shows and handles any events.  Please note that this does not show any data but rather controls what the view shows.

 

Getting Started

We start with a blank MVC application and create a Web API controller and add in some models that will be returned from the API.  I have chosen for a list of blog posts.  The structure of the post object is pretty simple:

    public class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Body { get; set; }
        public string Author { get; set; }
        public DateTime PostedDate { get; set; }
    }

In the API controller I have chosen to use two useful Nuget Packages:

The controller will be simple,  it will return a random number of posts from 10 to  100 with random data in it:

    public class BlogPostController : ApiController
    {
        [HttpGet]
        public IList Get()
        {
            PersonNameGenerator generator = new PersonNameGenerator();
            Random random = new Random();
            return Enumerable.Range(0, random.Next(10, 100))
                             .Select(x => new Post
                                 {
                                     Id = x,
                                     Author = generator.GenerateRandomFirstAndLastName(),
                                     Body = Ipsum.GetPhrase(100),
                                     PostedDate = DateTime.Now,
                                     Title = Ipsum.GetPhrase(10)
                                 })
                             .ToList();
        }

        [HttpPost]
        public bool Post(Post post)
        {
            //Simple validation
            if (post != null && 
                !string.IsNullOrEmpty(post.Author) &&
                !string.IsNullOrEmpty(post.Title) &&
                !string.IsNullOrEmpty(post.Body))
            {
                return true;
            }
            return false;
        }
    }

As you can see I have also included a “save” method that will allow the front-end to send a new post to be saved.   This method will only do simple validation, i.e. check to see whether there is a author title and post.

The ViewModel

As stated above the view model controls what View shows and handles any events.  By using the keywords above in the data-bind attribute knockout knows what methods to call if there is an event.  Here is the code that controls the view:

    
    function UiViewModel() {
        //Vars
        this.headerText = "Welcome to Knockout Tutorial",
        this.postText = ko.observable("");
        this.titleText = ko.observable("");
        this.author = ko.observable("");

        //Observables
        this.blogPosts = ko.observableArray([{ Title: "No Data Yet!", Body: "Click on the button to load data from the server" }]);

        //Functions
        this.getPosts = function () {
            var self = this;
            $.ajax({
                type: "GET",
                url: "/api/BlogPost",
                data: null,
                contentType: "application/json",
                success: function (data) {
                    self.blogPosts(data);
                },
                error: function () {
                    alert("Error in loading data");
                }
            });
        },

        this.savePost = function () {
            var self = this;
            $.ajax({
                type: "POST",
                url: "/api/BlogPost",
                data: JSON.stringify({ Title: self.titleText(), Body: this.postText(), author: this.author(), PostedDate: new Date() }),
                contentType: "application/json",
                success: function (data) {
                    if (data)
                        alert("Saved");
                },
                error: function () {
                    alert("Error in loading data");
                }
            });
        }
    }

The view model above is very simple but shows the variables that are bound to the controls to store the data for a new post as a user types it in as well as the ajax calls to retrieve posts as well as save a new post.

The View

The view is very simple.  The thing to note here is the data-bind statements that tell knockout what to do.

Knockout bindings:

  • With: (usage: data-bind=”with: UiViewModel”): This will tell knockout that everything in this element (and its child elements) relate this object.
  • Click: (usage: data-bind=”click: getPosts”): This will bind the onclick event to the getPosts method in the view model.
  • Value: (usage: data-bind=”value: titleText”): This will bind the value of the property to an element.
  • Text: (usage: data-bind=”text: headerText”): This will display the text value of the property in the element.
  • Foreach: (usage: data-bind=”foreach: blogPosts”): This will iterate through a collection of elements and set the with statement (See above) in the element so you wont have to.
  • Checked: (usage: data-bind=”checked: isPost"): This sets the checked attribute of a radio button or checkbox
  • Options: (usage: <select data-bind=”options: selectOptions, optionsText: ‘Id’, value: Name”></select>): This sets the options of a drop down list.  You are able to set what the value and text are with the parameters above.

If you would like to download the code I have used, you can find it here: github

Close