Knockout html binding not working (bound to a function calling a partial view) in ASP .NET MVC

asp.net-mvc, c#, knockout.js, razor

Solution

As Miroslav Popovic explains, the problem is that the AJAX request is asynchronous, so the `return data` is ignored and there is no return value from your call to `getHtml`.

I would suggest using a custom binding that handles the asynchronous HTML loading (I've put a working example here).

This works by taking 2 parameters to the asyncHtml: a function to call that takes a success callback as it's final parameter (plus any other parameters) and an array of the parameters that need to be passed to that function.

<div id="myPartialDiv" data-bind="asyncHtml: { source: getHtml, params: [123] }">Loading...</div>

The custom binding then grabs these values, concats a custom callback onto the parameters that are passed to it, and calls the specified function:

ko.bindingHandlers.asyncHtml = {
    init: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var parameters = value.params.concat([function(data) {
           $(element).html(data); 
        }]);
        value.source.apply(null, parameters);
    }
};

Finally we can re-implement our view model HTML-retrieving method to make the POST call and invoke the new success handler:

var ViewModel = function() {
    this.getHtml = function(issueId, callback) {
        $.ajax(
            {
                type: "POST",
                url: "/echo/html/",
                data: {
                        html: "<p>server response " + issueId + "</p>",
                        delay: 1
                    },
                success: callback,
                dataType: "text"
            });            
    };
};

Note: for this example I am using the jsFiddle `echo` to post back a random response

Problem

I have an ASP .NET MVC application, additonally I am using Knockout 2.0.0. I created a partial view which I would like to render to the page using knockout. The partial needs to be rendered within a Knockout foreach statement. I am unable to get the knockout HTML binding to work, and so I'm currently using a hack to put the html into the div using JQuery. There is a lot of html on this page, so it's not possible to post all of the source code, so I will try and post the pertinent code: ``` <div data-bind="foreach:issues"> @* SNIP - A lot of other html here*@ <div id="myPartialDiv" data-bind="html: $parent.getHtml(issueId())"> </div> </div> ``` Further down I have the following javascript function on my KO View Model (I have commented out my hack and included the code that returns HTML): ``` var getHtml = function (issueId) { var baseUrl = '@Url.Action("GetHtmlAction","MyController")'; $.ajax( { type: "POST", url: baseUrl, data: "&issueId=" + issueId, success: function (data) { //$('#mypartialDiv').html(data); return data; }, error: function (req, status, error) { //$('#myPartialDiv').html('Something went wrong.'); return 'Something went wrong.' }, dataType: "text" }); } ``` The code above results in no data being rendered to the page. USing Chrome debug tools, I see that there are no javascript errors occuring, and knockout is simply not binding the html of the div to the results returned from the getHtml function. What am I doing wrong? Thanks

Original source