我有一个问题是使用ajax重新加载部分视图。
我在部分视图中有我的国家/地区表单,最初当我加载主页面时,所有内容都正确呈现。
如下图所示,我可以使用自动完成功能搜索国家/地区,我可以从我的组合框中选择一个国家/地区(两者都是kendo-mvc controntrols)
当我从自动填充中选择一个并尝试通过ajax加载所选国家/地区的信息时,问题就出现了。重新加载表单,显示信息但控件未正确呈现。自动完成停止工作,组合框呈现为普通文本框,显示CountryID而不是Country name。
我认为的代码
@using (Html.BeginForm("Index", "CountryManagement", FormMethod.Post, new { id = "country-form" }))
{
@Html.ValidationSummary(true);
<div id="form-content">
@Html.Partial("_CountryForm", Model)
</div>
}
我的部分视图中的代码
<div class="form-group">
@Html.Label("Search Country", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-3">
@(Html.Kendo().AutoCompleteFor(m => m.Search)
.DataTextField("Designation")
//.DataValueField("CountryID")
.Filter("contains")
.MinLength(2)
.DataSource(d => { d.Read(r => r.Action("SearchCountry", "Common")); })
.Events(e => e.Change("onChange")).Deferred()
)
</div>
</div>
我的控制器中的代码
[HttpPost]
public PartialViewResult Edit(int id)
{
//HTTP GET: api/Country/CountryDetails?id={id}&lang={lang}
dynamic model = //code to get selcted country data
return PartialView("_CountryForm", model);
}
我的.js文件中的代码
function onChange() {
if ($("#Search").data("handler")) {
var data = $("#Search").data("handler").dataSource.data();
var country = data.find(x => x.Designation == $("#Search").val());
console.log("Country")
if (country) {
var request = $.post('/CountryManagement/Edit', { id: country.CountryID });
request.success(function (data) {
$("#form-content").html(data);
});
}
}
}
页面加载时生成的HTML代码(仅限自动填充和下拉列表)
<div class="form-group">
<label class="control-label col-md-2" for="Search_Country">Search Country</label>
<div class="col-md-3">
<span tabindex="-1" role="presentation" class="k-widget k-autocomplete k-header k-state-default k-state-hover"><input data-val="true" data-val-length="Description must have between 1 and 150 characters" data-val-length-max="150" data-val-length-min="1" id="Search" name="Search" type="text" data-role="autocomplete" class="k-input" autocomplete="off" role="textbox" aria-haspopup="true" aria-disabled="false" aria-readonly="false" aria-owns="Search_listbox" aria-autocomplete="list" has-focus="false" style="width: 100%;"><span class="k-icon k-loading" style="display:none"></span></span>
</div>
</div>
<br>
<br>
<div class="form-group">
<label class="control-label col-md-2" for="Country">Country</label>
<div class="col-md-3">
<span class="k-widget k-combobox k-header"><span tabindex="-1" unselectable="on" class="k-dropdown-wrap k-state-default"><input name="CountryID_input" class="k-input" type="text" autocomplete="off" title="" role="combobox" aria-expanded="false" tabindex="0" aria-disabled="false" aria-readonly="false" aria-autocomplete="list" aria-owns="CountryID_listbox" has-focus="false" style="width: 100%;"><span tabindex="-1" unselectable="on" class="k-select"><span unselectable="on" class="k-icon k-i-arrow-s" role="button" tabindex="-1" aria-controls="CountryID_listbox">select</span></span></span><input data-val="true" data-val-number="The field CountryID must be a number." id="CountryID" name="CountryID" type="text" value="0" data-role="combobox" aria-disabled="false" aria-readonly="false" has-focus="false" style="display: none;"></span>
<span class="field-validation-valid text-danger" data-valmsg-for="CountryID" data-valmsg-replace="true"></span>
</div>
</div>
在partialview重新加载时生成的HTML代码(仅限自动完成和下拉列表)
<div class="form-group">
<label class="control-label col-md-2" for="Search_Country">Search Country</label>
<div class="col-md-3">
<input data-val="true" data-val-length="Description must have between 1 and 150 characters" data-val-length-max="150" data-val-length-min="1" id="Search" name="Search" type="text" value="South Africa">
</div>
</div>
<br>
<br>
<div class="form-group">
<label class="control-label col-md-2" for="Country">Country</label>
<div class="col-md-3">
<input data-val="true" data-val-number="The field CountryID must be a number." id="CountryID" name="CountryID" type="text" value="1003">
<span class="field-validation-valid text-danger" data-valmsg-for="CountryID" data-valmsg-replace="true"></span>
</div>
</div>
我不确定这是否是ASP.Net MVC部分视图,Kendo控件或部分视图重新加载时应重新运行的一些脚本的问题。 有人可以帮帮我吗?
答案 0 :(得分:3)
在Telerik论坛的深层次尝试无数次尝试失败后,我终于找到了问题所在。
部分视图中的Kendo小部件不应使用延迟初始化。
@(Html.Kendo().AutoCompleteFor(m => m.Search)
///.. code removed to reduce complexity
.Events(e => e.Change("onChange")).Deferred()
)
当视图作为服务器请求加载时,它会正确呈现,因为在布局文件的末尾,所有使用@Html.Kendo().DeferredScripts()
初始化延迟初始化的小部件。但是,当通过ajax重新加载局部视图时,永远不会发生延迟脚本初始化,因为脚本不会重新运行。
向局部视图添加@Html.Kendo().DeferredScripts()
解决了ajax重新加载的问题,但在服务器加载时出现问题,因为:1 - 延迟初始化将运行两次,2 - 因为kendo小部件具有jquery依赖性并且将是在jquery脚本包含在页面之前运行。
我发现的解决方案是不要对小部件的初始化进行处理,但是这将使我们回到上面关于jquery依赖性的观点。尽管我试图避免它,唯一真正有用的是在页眉中包含jquery。所有其他脚本(验证,kendo,自定义等)仍然位于底部,但主要的jquery脚本位于顶部。现在我的部分视图完全加载到服务器或ajax请求上。
TL; DR;
希望有更好的方法可以做到这一点,但现在它可以解决问题。
答案 1 :(得分:1)
所以我在论坛上搜索,也找不到合适的修复程序。但我做了以下,似乎工作得很好。基本上,如果部分正常呈现,则布局视图处理延迟脚本,但如果请求是通过AJAX,则部分视图将继续并呈现它们。
我把它放在我的部分底部:
@if (Context.Request.IsAjaxRequest())
{
<div id="kendo-scripts">
@Html.Kendo().DeferredScripts()
</div>
}
仅供参考,将.Deffered()留在你的剑道对象的末尾也是不明显的。
答案 2 :(得分:1)
检查任何页面脚本初始化错误!
我在这里遇到了同样的问题,烧了3天,对我来说,最终的问题是在no MutationObserver周围有一个页面初始化脚本脚本,在较旧的野生动物园浏览器中不可用。添加了polyfill并修复了初始化错误之后,使用Kendo控件动态注入ajax内容即可正常工作,而无需延迟。希望这可以使其他人免于沮丧。
此初始化错误影响了Telerik依赖于呈现其发出的脚本块中的每个控件的任何ajax内容的jquery的就绪初始化程序回调。