Kendo UI for jQuery使用教程:自定义小部件(三)

本教程主要介绍如何使用Kendo UI通过继承基本窗口小部件类为您提供创建自定义窗口小部件的选项,Kendo UI for jQuery是创建现代Web应用程序的最完整UI库,欢迎大家免费下载最新版!

Kendo UI目前最新提供Kendo UI for jQuery、Kendo UI for Angular、Kendo UI Support for React和Kendo UI Support for Vue四个控件。Kendo UI for jQuery是创建现代Web应用程序的最完整UI库。

Kendo UI通过继承基本窗口小部件类为您提供创建自定义窗口小部件的选项。

使用MVVM

1. 为了使该小部件具有MVVM-aware,您需要定义一些事件。具体来说,公开dataBinding事件和dataBound事件。在使用小部件对DOM进行更改之前,将要调用dataBinding事件。这使MVVM有机会遍历将要突变的片段,并取消绑定当前绑定的任何片段。 第二个事件是dataBound事件,它使MVVM返回片段,并重新绑定必要的事件, 这些事件通过小部件上的事件对象公开。这些事件是字符串,因此在开发Kendo UI窗口小部件时,将它们定义为窗口小部件顶部的常量,作为Kendo UI使用模式的一部分。

通过将这些事件公开为MVVM可以监听的事件,您可以在小部件和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 or developers - API for other purposes.  // These events support MVVM bound items in the template for loose coupling with 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 or developers - API for other purposes.  // These events support MVVM bound items in the template. for loose coupling with 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  ],// MVVM expects an array of DOM elements that 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 datasource over 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件事:

  • 分配数据源,或从数组或配置对象建立。
  • 从DataSource读取(如果启用了autoBind且尚未从DataSource读取)。
  • 将数据源上的change事件绑定到您手动处理的内部刷新方法。

由于您可能已经在数据源上绑定了一次更改事件,因此请确保在必要时取消绑定。如果不这样做,则小部件将保留所有绑定的列表,并多次执行刷新功能。 同样,MVVM将监听尚未定义的内部_refreshHandler函数,您需要将内部_refreshHandler指向公开的刷新方法。不过,请首先检查绑定到DataSource上的change事件的公共刷新和内部_refreshHandler之间是否存在现有连接,如果存在,则仅删除对更改事件的绑定。 如果内部_refreshHandler与公共刷新功能之间没有连接,则需要创建它。这是通过$ .proxy jQuery方法完成的,该方法使用正确的上下文(即小部件本身)调用公共刷新。 最后,重新绑定到DataSource的change事件。

如果您以前没有使用过代理jQuery函数,则以下内容可能会造成混淆,在调用_refreshHandler时,它应该执行公共刷新小部件函数,并且在该刷新函数内部,这将是一个指向窗口小部件本身,而不是窗口之类的其他东西。 由于JavaScript中关键字的值始终在变化,因此这是确保刷新函数执行时范围正确的一种好方法。

_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 if using 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. 在公共刷新中触发dataBinding和dataBound事件。 请注意,dataBinding发生在更改DOM之前,而dataBound发生在此之后。

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 widget UI).  that.element.html(html);// Trigger the dataBound event.  that.trigger(DATABOUND);  }

现在,您的窗口小部件中已完全启用了MVVM。 定义小部件,如下面的示例所示。

<div data-role="repeater" data-bind="source: dataSource"></div><script>var viewModel = kendo.observable({dataSource:  new kendo.data.DataSource({transport: {read: "Customers/Orders",dataType: "json"}})});kendo.bind(document.body.children, viewModel);</script>

注意,小部件现在通过数据绑定绑定到ViewModel内部的dataSource变量。 这意味着,如果我们在数据源中添加客户端项,则您的窗口小部件将立即反映更改,而无需重新渲染任何内容。

在下面的完整示例中,请注意将项目添加到数据源时,它会立即反映在Repeater小部件中。

```dojo<label for="newItem">Enter A New Item</label><input id="newItem" data-bind="value: newItem" class="k-input" /><button class="k-button" data-bind="click: add">Add Item</button><div data-role="repeater" data-bind="source: items" data-template="template"></div><script type="text/x-kendo-template" id="template">  <div style="color: salmon; margin-right: 10px'"><h1>#= data #</h1></div>  </script><script>  var viewModel = kendo.observable({  items: ["item1", "item2", "item3"],  newItem: null,  add: function(e) {  if (this.get("newItem")) {  this.get("items").push(this.get("newItem"));  }  }  });kendo.bind(document.body, viewModel);  </script>```
使用价值有限的小部件

为了使小部件支持值绑定,您需要:

  • 向窗口小部件添加一个value方法,该方法设置当前窗口小部件的值,如果未传递任何参数,则返回当前值。
  • 更改窗口小部件值时触发窗口小部件更改事件。

以下示例演示如何创建一个简单的输入小部件,以选择焦点值。

1. 创建窗口小部件并实现所需的功能。

(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. 触发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);  }  });

以下示例结合代码片段并展示完整的代码。

<script>(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._changeHandler = $.proxy(this._change, this);  this.element.on("change", this._changeHandler);  this.element.on("focus", this._focus);  },options: {  name: "SelectedTextBox"  },_change: function () {  this._value = this.element.val();  this.trigger("change");  },_focus: function () {  this.select();  },value: function (value) {  if (value !== undefined) {  this.element.val(value);  } else {  return this.element.val();  }  },destroy: function () {  this.element.off("change", this._changeHandler);  this.element.off("focus", this._focus);  }  });kendo.ui.plugin(SelectedTextBox);  })(jQuery);  </script><input type="text" data-role="selectedtextbox" data-bind="value:foo" /><script>  var viewModel = kendo.observable({  foo: "bar"  });kendo.bind(document.body, viewModel);  </script>

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年8月26日
下一篇 2019年8月27日

相关推荐

发表回复

登录后才能评论