4

我有一个 ASP .NET MVC 应用程序,另外我正在使用 Knockout 2.0.0。我创建了一个局部视图,我想使用敲除渲染到页面。部分需要在 Knockout foreach 语句中呈现。我无法让淘汰赛 HTML 绑定工作,因此我目前正在使用 hack 将 html 放入使用 JQuery 的 div 中。

这个页面有很多html,所以无法贴出所有的源代码,所以我会尝试贴出相关代码:

<div data-bind="foreach:issues">
    @* SNIP - A lot of other html here*@
    <div id="myPartialDiv" data-bind="html: $parent.getHtml(issueId())">
    </div>  
</div>

再往下,我的 KO 视图模型上有以下 javascript 函数(我已注释掉我的 hack 并包含返回 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"
                });
         }

上面的代码导致没有数据呈现到页面。使用 Chrome 调试工具,我看到没有发生 javascript 错误,并且敲除根本没有将 div 的 html 绑定到 getHtml 函数返回的结果。

我究竟做错了什么?

谢谢

4

2 回答 2

4

正如 Miroslav Popovic 解释的那样,问题在于 AJAX 请求是异步的,因此return data被忽略并且您的调用没有返回值getHtml.

我建议使用处理异步 HTML 加载的自定义绑定(我在这里放了一个工作示例)。

这通过将 2 个参数传递给 asyncHtml 来工作:一个要调用的函数,它接受一个成功回调作为它的最终参数(加上任何其他参数),以及一个需要传递给该函数的参数数组。

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

然后自定义绑定获取这些值,将自定义回调连接到传递给它的参数上,并调用指定的函数:

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);
    }
};

最后,我们可以重新实现我们的视图模型 HTML 检索方法来进行 POST 调用并调用新的成功处理程序:

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"
            });            
    };
};

注意:对于这个例子,我使用 jsFiddleecho来回发一个随机响应

于 2012-06-12T10:10:28.417 回答
3

$.ajax是一个异步调用。当你调用它时,执行将继续到getHtml函数中的下一条语句。由于这是最后一条语句,该getHtml函数将返回undefined.

关于您的return data;... 此返回在成功回调函数中。数据将是函数的结果,而不是父getHtml函数。此外,getHtml已经完成。您无法从中返回结果。

在你的视图模型中有一个可观察的属性怎么样html,然后找到一些其他触发getHtml函数的方法(按钮单击,其他一些成功回调,issueId属性更改......),这将反过来设置'html'属性值. 然后,您可以简单地将数据绑定到该属性data-bind="html: html"

于 2012-06-12T09:42:12.143 回答