Kendo UI目前最新提供KendoUI for jQuery、KendoUI for Angular、KendoUI Support for React和KendoUI Support for Vue四個控件。Kendo UI for jQuery是創(chuàng)建現代Web應用程序的完整UI庫。
Kendo UI通過繼承基本窗口小部件類為您提供創(chuàng)建自定義窗口小部件的選項。

使用MVVM
1. 為了使該小部件具有MVVM-aware,您需要定義一些事件。具體來說,公開dataBinding事件和dataBound事件。在使用小部件對DOM進行更改之前,將要調用dataBinding事件。這使MVVM有機會遍歷將要突變的片段,并取消綁定當前綁定的任何片段。第二個事件是dataBound事件,它使MVVM返回片段,并重新綁定必要的事件,這些事件通過小部件上的事件對象公開。這些事件是字符串,因此在開發(fā)Kendo UI窗口小部件時,將它們定義為窗口小部件頂部的常量,作為Kendo UI使用模式的一部分。
通過將這些事件公開為MVVM可以監(jiān)聽的事件,您可以在小部件和MVVM核心引擎之間實現松散耦合。這意味著,如果您不公開這些事件,則MVVM將不會知道窗口小部件的生命周期。 這是一個非常好的架構,這是一個非常好的架構,因為它可以確保您的小部件不會破壞其他不知道的MVVM綁定。
var DATABINDING = "dataBinding",
DATABOUND = "dataBound",
CHANGE = "change"
var Repeater = kendo.ui.Widget.extend({
init: function(element, options) {
…
},
options{
…
},
// The events are used by other widgets ordevelopers – API for other purposes.
// These events support MVVM bound items in the template for loose couplingwith MVVM.
events: [
// Call before mutating DOM.
// MVVM will traverse DOM, unbind any bound elements or widgets.
DATABINDING,
// Call after mutating DOM.
// Traverses DOM and binds ALL THE THINGS.
DATABOUND
]
});
2. MVVM希望您從窗口小部件中公開DOM片段,該片段代表每一行或每個重復的數據元素。您必須返回最外面的元素,MVVM才能使用。雖然有所不同,但這通常只是this.element.children。 由于呈現的每個模板項目都是一個DOM片段,并附加到綁定的元素上,因此您只需要這些。通過使它在Items對象之外可用,將其公開用于MVVM。
var DATABINDING = "dataBinding",
DATABOUND = "dataBound",
CHANGE = "change"
var Repeater = kendo.ui.Widget.extend({
init: function(element, options) {
…
},
options{
…
},
// The events are used by other widgets ordevelopers – API for other purposes.
// These events support MVVM bound items in the template. for loose coupling withMVVM.
events: [
// Call before mutating DOM.
// MVVM will traverse DOM, unbind any bound elements or widgets.
DATABINDING,
// Call after mutating DOM.
// Traverses DOM and binds ALL THE THINGS.
DATABOUND
],
// MVVM expects an array of DOM elementsthat represent each item of the datasource.
// Has to be the children of the outermost element.
items: function() {
return this.element.children();
}
});
3. 由于可以使用MVVM更改數據源,因此需要實現setDataSource函數。 當在ViewModel中設置數據源時,MVVM會調用此方法。 將內部DataSource引用設置為與MVVM傳遞的引用相等,然后使用已定義的dataSource()函數重新構建DataSource。
// For supporting changing the datasourceover MVVM.
setDataSource: function(dataSource) {
// Set the internal datasource equal to the one passed in by MVVM.
this.options.dataSource = dataSource;
// Rebuild the datasource if necessary or just reassign.
this._dataSource();
}
4. 您需要對分配或構建數據源的方法進行一些小的調整,在init中調用的_dataSource方法可完成3件事:
由于您可能已經在數據源上綁定了一次更改事件,因此請確保在必要時取消綁定。如果不這樣做,則小部件將保留所有綁定的列表,并多次執(zhí)行刷新功能。同樣,MVVM將監(jiān)聽尚未定義的內部_refreshHandler函數,您需要將內部_refreshHandler指向公開的刷新方法。不過,請首先檢查綁定到DataSource上的change事件的公共刷新和內部_refreshHandler之間是否存在現有連接,如果存在,則僅刪除對更改事件的綁定。如果內部_refreshHandler與公共刷新功能之間沒有連接,則需要創(chuàng)建它。這是通過$ .proxy jQuery方法完成的,該方法使用正確的上下文(即小部件本身)調用公共刷新。 最后,重新綁定到DataSource的change事件。
如果您以前沒有使用過代理jQuery函數,則以下內容可能會造成混淆,在調用_refreshHandler時,它應該執(zhí)行公共刷新小部件函數,并且在該刷新函數內部,這將是一個指向窗口小部件本身,而不是窗口之類的其他東西。由于JavaScript中關鍵字的值始終在變化,因此這是確保刷新函數執(zhí)行時范圍正確的一種好方法。
_dataSource: function() {
var that = this;
// If the DataSource is defined and the_refreshHandler is wired up, unbind because
// you need to rebuild the DataSource.
if ( that.dataSource && that._refreshHandler ) {
that.dataSource.unbind(CHANGE, that._refreshHandler);
}
else {
that._refreshHandler = $.proxy(that.refresh, that);
}
// Returns the datasource OR creates one ifusing array or configuration object.
that.dataSource = kendo.data.DataSource.create(that.options.dataSource);
// Bind to the change event to refresh the widget.
that.dataSource.bind( CHANGE, that._refreshHandler );
if (that.options.autoBind) {
that.dataSource.fetch();
}
}
5. 在公共刷新中觸發(fā)dataBinding和dataBound事件。 請注意,dataBinding發(fā)生在更改DOM之前,而dataBound發(fā)生在此之后。
refresh: function() {
var that = this,
view = that.dataSource.view(),
html = kendo.render(that.template, view);
// Trigger the dataBinding event.
that.trigger(DATABINDING);
// Mutate the DOM (AKA build the widgetUI).
that.element.html(html);
// Trigger the dataBound event.
that.trigger(DATABOUND);
}
現在,您的窗口小部件中已完全啟用了MVVM。 定義小部件,如下面的示例所示。
注意,小部件現在通過數據綁定綁定到ViewModel內部的dataSource變量。 這意味著,如果我們在數據源中添加客戶端項,則您的窗口小部件將立即反映更改,而無需重新渲染任何內容。
在下面的完整示例中,請注意將項目添加到數據源時,它會立即反映在Repeater小部件中。
“`dojo
#= data#
“`
使用價值有限的小部件
為了使小部件支持值綁定,您需要:
以下示例演示如何創(chuàng)建一個簡單的輸入小部件,以選擇焦點值。
1. 創(chuàng)建窗口小部件并實現所需的功能。
(function ($) {
var kendo = window.kendo;
var SelectedTextBox =kendo.ui.Widget.extend({
init: function (element, options) {
kendo.ui.Widget.fn.init.call(this, element, options);
this.element.on("focus",this._focus);
},
options: {
name: "SelectedTextBox"
},
_focus: function () {
this.select();
},
destroy: function () {
this.element.off("focus", this._focus);
}
});
kendo.ui.plugin(SelectedTextBox);
})(jQuery);
2. 添加一個value方法。
var SelectedTextBox =kendo.ui.Widget.extend({
…
value: function (value) {
if (value !== undefined) {
this.element.val(value);
} else {
return this.element.val();
}
}
});
3. 觸發(fā)change事件。
var SelectedTextBox =kendo.ui.Widget.extend({
init: function (element, options) {
…
this._changeHandler = $.proxy(this._change, this);
this.element.on("change", this._changeHandler);
},
…
_change: function () {
this.trigger("change");
},
destroy: function () {
this.element.off("change", this._changeHandler);
this.element.off("focus", this._focus);
}
});
以下示例結合代碼片段并展示完整的代碼。