0

I am working on an app which connects to XSockets via WCF and am able to get the data on the client side. I want to display this data using Grid.Mvc and have seen samples of using knockout.js, but I am not sure how to push this into my IEnumerable model so that I can see the View updated.

I have tried using the following code

@{
  var initialData = new JavaScriptSerializer().Serialize(Model);  }

$(function() {
     ws = new XSockets.WebSocket("ws://127.0.0.1:4502/Book");

    var vm = ko.mapping.fromJSON('@Html.Raw(initialData)');

    ko.applyBindings(vm);

      //Just write to the console on open
    ws.bind(XSockets.Events.open, function (client) {
        console.log('OPEN', client);

     ws.bind('SendBook', function (books) {

        jQuery.ajax({
                type: "POST",
                url: "@Url.Action("BooksRead", "Home")",
                data: JSON.stringify(books),
                dataType: "json",
                contentType: "application/json",
                success: function (result) {

                 //This doesnt work   
                 /vm.push({Name:'Treasure Island',Author:'Robert Louis Stevenson'});

                //vm.pushAll(result)
                },
                error: function (result){},
                async: false
            });
        });        
    });

I am always receiving a null value for the parameter in the the BooksRead JsonResult method.

The model is a simple one

 public class BookModel
 {
    public string Name {get; set;}

    public string Author {get; set;}
 } 

I am returning a BookModel IEnumerable as my Model from the home controller on load and would want to insert new books into it as I receive them in the socket bind. This is because I am using it to generate the grid.

       @Html.Grid(Model).Columns(c =>
       {
         c.Add(b => b.Name).Titled("Title");
         c.Add(b => b.Author);
       })

I would appreciate any pointers and guidance as to how I can go about achieving this.Many thanks

UPDATE

I am now able to get values in the controller action method after removing the dataType & contentType parameters from the ajax call. The controller method is as follows

public JsonResult BooksRead(string books)
    {
        BookModel data = JsonConvert.DeserializeObject<BookModel>(books);

        List<BookModel> bookList = (List<BookModel>) TempData["books"];

        if (bookList != null  && data != null)
        {
            bookList.Add(data);

            var bookString = JsonConvert.SerializeObject(bookList);

            return Json(bookString); 
        }

        return Json("");
    }

I have added a vm.push call in the success handler and am passing the result value to it, but it still doesnt seem to add the new book in the Model. It seems I am doing it the wrong way as I am new to knockout js, jquery & ajax and trying to learn as I go along so please pardon my ignorance

UPDATE 2

I have made a few more changes.Like Uffe said, I have removed the Ajax call. I am adapting the StockViewModel from the StockTicker example to my BookViewModel and have added a parameter to the ctor to take in my IEnumerable model. This works & the item is added. The AddOrUpdate is working fine too & the objects are added to the collection but how can I get my model to be updated in the grid.

@{
    var initialData = @Html.Raw(JsonConvert.SerializeObject(Model));
 }

   $(function() {

   vm = new BookViewModel(@Html.Raw(initialData));

    ko.applyBindings(vm);

    ws = new XSockets.WebSocket("ws://127.0.0.1:4502/Book"); 

    //Just write to the console on open
    ws.bind(XSockets.Events.open, function(client) {
        console.log('OPEN', client);

        ws.bind('SendBook', function (msg) {

           vm.AddOrUpdate(msg.book);
        });

        ws.bind(XSockets.Events.onError, function (err) {
            console.log('ERROR', err);
        }); 
    });
});

The ViewModel is as follows

var BookViewModel = function(data) {

//this.Books = ko.observableArray(data);
this.Books = ko.observableArray(ko.utils.arrayMap(data, function(book) {
    return new BookItem(book);
}));

this.AddOrUpdate = function(book) { 
               this.Books.push(new BookItem(book));       
};

};

tribal
  • 219
  • 3
  • 14
  • Maybe I am missing something here, but why are you using AJAX at all if you are using XSockets? Obviously you are using a websocket capable browser. – Uffe Jun 09 '14 at 18:39
  • Hi Uffe, Thanks for a great framework. All I want to do is update my C# IEnumerable model inside the bind call by pushing the received data into it so I can see my grid update without reload. I am a bit lost with knockout, can you give me any pointers – tribal Jun 10 '14 at 16:47

0 Answers0