为什么小部件的事件在视图完全呈现之前触发?
Why widgets' events triggered before view completely rendered?
假设我们有这样的视图:
<script id="my-view" type="text/x-kendo-template">
<div>
<input data-text-field="name"
data-value-field="id"
data-role="dropdownlist"
data-bind="source:wellDataSource,events:{change:onWellChange,dataBound:onWellDataBound}" />
<div data-role="tabstrip" data-bind="visible:isAnyWellExist">
<ul class="bd-doc-navigation-tabstrip" data-freezable="false">
<li class="k-state-active">Home</li>
<li>Products</li>
<li>About</li>
<li>...</li>
</ul>
</div>
</script>
JS:
var _view = new kendo.View("my-view", { model: _viewModel});
_view.render("#container");
当我渲染视图时,我希望渲染所有三个小部件,然后触发它们的事件,但是当 dropdownlist 渲染完成时,它是 databinding 和 databound 事件在 tabstrip 和 grid 呈现之前触发。所以我无法访问这些事件中的 tabstrip 和 grid 小部件。
为什么会这样?是否有任何解决方案或解决方法来确保事件在完全呈现视图后发生?
每个小部件单独加载且彼此并行,因此很可能一个小部件已完全数据绑定,而另一个小部件尚不存在。事件不会等到页面完全加载。
根据您的实施方式,解决方法可能是将访问标签条和网格的代码移动到:
$(document).ready(function() {
...
});
要强制 Kendo 数据源同步运行,您可以尝试使用 async: false
配置数据源传输:
var datasource = new kendo.data.DataSource({
transport: {
read: {
async: false,
url: function (data) {
return "/Home/Product";
},
dataType: "json"
},
},
});
我找到了一种检查是否所有小部件都已绑定的方法。参见 here。
示例:
<script>
$(document).ready(function() {
var promises = [];
var change = function() {
this.deferred.resolve();
}
var categories = $("#categories").kendoDropDownList({
dataTextField: "CategoryName",
dataValueField: "CategoryID",
dataSource: {
type: "odata",
serverFiltering: true,
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Categories"
},
requestStart: function() {
this.deferred = $.Deferred();
promises.push(this.deferred.promise());
}
}
}).data("kendoDropDownList");
var products = $("#products").kendoDropDownList({
dataTextField: "ProductName",
dataValueField: "ProductID",
dataSource: {
type: "odata",
serverFiltering: true,
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Products"
},
requestStart: function() {
this.deferred = $.Deferred();
promises.push(this.deferred.promise());
}
}
}).data("kendoDropDownList");
categories.dataSource.bind("change", change);
products.dataSource.bind("change", change);
$.when.apply(null, promises)
.done(function() {
console.log("done");
console.log(categories.value());
console.log(products.value());
});
});
</script>
Kendo DropDownList 有一个 DataSource
,仅供参考,事件 DataBinding
和 DataBound
在从服务器收集数据时自动触发。
因此,要阻止它这样做,您必须阻止 DropDownList 的数据初始化。您可以将 DropDownList AutoBind
属性 更改为 false
,这样它就不会在初始化阶段向服务器发出请求。页面完全呈现后,您可以触发它的 DataSource
来调用 read
方法。
你的代码应该是这样的
<input data-text-field="name"
data-value-field="id"
data-role="dropdownlist"
data-bind="source:wellDataSource,events: change:onWellChange,dataBound:onWellDataBound}"
data-auto-bind="false" />
$(document).ready(function() {
$("#dropdown").data().kendoDropDownList.dataSource.read();
});
假设我们有这样的视图:
<script id="my-view" type="text/x-kendo-template">
<div>
<input data-text-field="name"
data-value-field="id"
data-role="dropdownlist"
data-bind="source:wellDataSource,events:{change:onWellChange,dataBound:onWellDataBound}" />
<div data-role="tabstrip" data-bind="visible:isAnyWellExist">
<ul class="bd-doc-navigation-tabstrip" data-freezable="false">
<li class="k-state-active">Home</li>
<li>Products</li>
<li>About</li>
<li>...</li>
</ul>
</div>
</script>
JS:
var _view = new kendo.View("my-view", { model: _viewModel});
_view.render("#container");
当我渲染视图时,我希望渲染所有三个小部件,然后触发它们的事件,但是当 dropdownlist 渲染完成时,它是 databinding 和 databound 事件在 tabstrip 和 grid 呈现之前触发。所以我无法访问这些事件中的 tabstrip 和 grid 小部件。
为什么会这样?是否有任何解决方案或解决方法来确保事件在完全呈现视图后发生?
每个小部件单独加载且彼此并行,因此很可能一个小部件已完全数据绑定,而另一个小部件尚不存在。事件不会等到页面完全加载。
根据您的实施方式,解决方法可能是将访问标签条和网格的代码移动到:
$(document).ready(function() {
...
});
要强制 Kendo 数据源同步运行,您可以尝试使用 async: false
配置数据源传输:
var datasource = new kendo.data.DataSource({
transport: {
read: {
async: false,
url: function (data) {
return "/Home/Product";
},
dataType: "json"
},
},
});
我找到了一种检查是否所有小部件都已绑定的方法。参见 here。
示例:
<script>
$(document).ready(function() {
var promises = [];
var change = function() {
this.deferred.resolve();
}
var categories = $("#categories").kendoDropDownList({
dataTextField: "CategoryName",
dataValueField: "CategoryID",
dataSource: {
type: "odata",
serverFiltering: true,
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Categories"
},
requestStart: function() {
this.deferred = $.Deferred();
promises.push(this.deferred.promise());
}
}
}).data("kendoDropDownList");
var products = $("#products").kendoDropDownList({
dataTextField: "ProductName",
dataValueField: "ProductID",
dataSource: {
type: "odata",
serverFiltering: true,
transport: {
read: "http://demos.kendoui.com/service/Northwind.svc/Products"
},
requestStart: function() {
this.deferred = $.Deferred();
promises.push(this.deferred.promise());
}
}
}).data("kendoDropDownList");
categories.dataSource.bind("change", change);
products.dataSource.bind("change", change);
$.when.apply(null, promises)
.done(function() {
console.log("done");
console.log(categories.value());
console.log(products.value());
});
});
</script>
Kendo DropDownList 有一个 DataSource
,仅供参考,事件 DataBinding
和 DataBound
在从服务器收集数据时自动触发。
因此,要阻止它这样做,您必须阻止 DropDownList 的数据初始化。您可以将 DropDownList AutoBind
属性 更改为 false
,这样它就不会在初始化阶段向服务器发出请求。页面完全呈现后,您可以触发它的 DataSource
来调用 read
方法。
你的代码应该是这样的
<input data-text-field="name"
data-value-field="id"
data-role="dropdownlist"
data-bind="source:wellDataSource,events: change:onWellChange,dataBound:onWellDataBound}"
data-auto-bind="false" />
$(document).ready(function() {
$("#dropdown").data().kendoDropDownList.dataSource.read();
});