我有一个ASP .NET MVC应用程序,另外我正在使用Knockout 2.0.0。我创建了一个局部视图,我想使用knockout渲染到页面。部分需要在Knockout foreach语句中呈现。我无法使淘汰HTML绑定工作,所以我目前正在使用hack将html放入div中使用JQuery。
此页面上有很多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 View模型上有以下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错误,并且knockout只是没有将div的html绑定到getHtml函数返回的结果。
我做错了什么?
由于
答案 0 :(得分:4)
正如Miroslav Popovic所解释的那样,问题是AJAX请求是异步的,因此return data
会被忽略,并且您对getHtml
的调用没有返回值。
我建议使用一个处理异步HTML加载的自定义绑定(我已经设置了一个工作示例here)。
这是通过将两个参数带到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"
});
};
};
注意:对于此示例,我使用jsFiddle echo
发回随机响应
答案 1 :(得分:3)
$.ajax
是异步调用。当您调用它时,执行将继续执行getHtml
函数中的下一个语句。由于这是最后一个语句,getHtml
函数将返回undefined
。
关于您的return data;
...此回复属于成功回调函数。数据将是 函数的结果,而不是父getHtml
函数的结果。此外,getHtml
已经完成。你无法从中返回结果。
如何在视图模型中使用名为html
的可观察属性,然后找到一些其他触发getHtml
函数的方法(按钮单击,其他一些成功回调,issueId属性更改... ),这将依次设置'html'属性值。然后,您可以简单地数据绑定到该属性data-bind="html: html"
。