HTML5 Web app开发工具Kendo UI Web教程:创建自定义组件(三)

205 篇文章 0 订阅
160 篇文章 0 订阅
转自: http://www.evget.com/article/2013/11/19/20077.html
概述: Kendo UI Web包含数百个创建HTML5 web app的必备元素,包括UI组件、数据源、验证、一个MVVM框架、主题、模板等。在前面的2篇文章《HTML5 Web app开发工具Kendo UI Web教程:创建自定义组件》中,已经对在Kendo UI Web中如何创建自定义组件的方法和步骤做了一些的讲解,本文将完成所有的创建内容。

    Kendo UI Web包含数百个创建HTML5 web app的必备元素,包括UI组件、数据源、验证、一个MVVM框架、主题、模板等。在前面的2篇文章《HTML5 Web app开发工具Kendo UI Web教程:创建自定义组件》中,已经对在Kendo UI Web中如何创建自定义组件的方法和步骤做了一些的讲解,本文将完成所有的内容。

模板绘制控件:

    通过Kendo UI的Templates渲染进行HTML输出,Kendo UI Templates允许你编译HTML和注入数据或表达式到被评估以及作为一个HTML字符串返回的DOM片段的HTML中。在

    Kendo UI中的所有组件都允许指定一种除组件使用的默认模版之外的模版。要指定模版,需要首先添加模版到选择对象中,并设置它的值为一个空的字符串,相反其他的配置设置,我们不会在这里设置它的默认值。

添加模版到选项:

1
2
3
4
5
options: {
     name:  "Repeater" ,
     autoBind:  true ,
     template:  ""
}

设置这个模版的默认值:

1
that.template = kendo.template(that.options.template ||  "<p><strong>#= data #</strong></p>" )

实现一个刷新功能:

    由于绑定到一个change方法,现在需要实现当DataSource改变或者是被直接调用的时候,这个refresh public函数会被调用,这个刷新方法就是我将要mutate DOM的地方。首先需要做的事情就是调用我们来自DataSource数据的that.dataSource.view(),接下来就是使用kendoRender,并随着DataSource数据通过一个模版,这个就是Kendo UI组件mutate DOM的方法。渲染方法应用数据到数据源并返回HTML字符串。

公有Refresh Function:

1
2
3
4
5
6
7
8
9
10
11
12
13
refresh:  function () {
     var that =  this ,
         view = that.dataSource.view(),
         html = kendo.render(that.template, view);
}
Mutate  DOM Element HTML:
refresh:  function () {
     var that =  this ,
         view = that.dataSource.view(),
         html = kendo.render(that.template, view);
 
     that.element.html(html);
}

数据源控件的完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
( function () {
     var kendo = window.kendo,
         ui = kendo.ui,
         Widget = ui.Widget,
 
     CHANGE =  "change" ;
 
     var Repeater = Widget.extend({
         init:  function (element, options) {
             var that =  this ;
 
             kendo.ui.Widget.fn.init.call(that, element, options);
             that.template = kendo.template(that.options.template ||  "<p><strong>#= data #</strong></p>" );
 
             that._dataSource();
         },
         options: {
             name:  "Repeater" ,
             autoBind:  true ,
             template:  ""
         },
         refresh:  function () {
             var that =  this ,
                 view = that.dataSource.view(),
                 html = kendo.render(that.template, view);
 
             that.element.html(html);
         },
         _dataSource:  function () {
             var that =  this ;
             // 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,  function () {
                 that.refresh();
             });
 
             if (that.options.autoBind) {
                 that.dataSource.fetch();
             }
         }
     });
 
     ui.plugin(Repeater);
 
})(jQuery);

    下面是一个演示,有两个组件在这里进行了初始化,第一个是使用一个简单的阵列作为数据源,第二个是使用的远程端点、模板、并声明初始化。

1
2
3
4
5
6
7
8
9
var dataSource =  new kendo.data.DataSource({
     data: [  "item1" "item2" "item3" ]
});
 
kendo.bind($( "#container" ));
 
$( "#repeater" ).kendoRepeater({
     dataSource: [  "item1" "item2" "item3" ]
});

组件MVVM Aware:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var DATABINDING =  "dataBinding" ,
     DATABOUND =  "dataBound" ,
     CHANGE =  "change"   
 
var Repeater = kendo.ui.Widget.extend({
 
     init:  function (element, options) {
         ...
     },
     options{
         ...
     },
 
     // events are used by other widgets / 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将会要我们公有代表着我们组件的每一行或者是每个重复元素的DOM 片段,我们需要返回使用到的对于MVVM的最外层的元素,在通常情况下是this.element.children。由于每个模版项目呈现的是一个与绑定元素相关的DOM片段,我们可以通过使它对项目对象不可用,来对MVVM公有它。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
var DATABINDING =  "dataBinding" ,
     DATABOUND =  "dataBound" ,
     CHANGE =  "change"   
 
var Repeater = kendo.ui.Widget.extend({
 
     init:  function (element, options) {
         ...
     },
     options{
         ...
     },
 
     // events are used by other widgets / 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.
     // should be the outermost element's children
     items:  function () {
         return this .element.children();
     }
});

改变数据源:

1
2
3
4
5
6
7
// for supporting changing the datasource via 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();
}

调整 _dataSource:

    对于我们用于指定和创建数据源的方法现在需要做一些调整。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
_dataSource:  function () {
 
     var that =  this ;
 
     // if the DataSource is defined and the _refreshHandler is wired up, unbind because
     // we 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();
     }
}

    果说在之前你没有使用过代理 jQuery 函数,现在可能会有一点混乱,当_refreshHandler被调用时都会被调整,公有刷新组件功能更以及内置的刷新功能也会相应的实现,这个也会引用该组件的本身,并不是其他的类似于窗口的东西。由于关键字的值总是用JS改变,当刷新功能执行的时候,这个是一个好的办法来确保正确的范围。

触发绑定/绑定事件:

    最后我们只需要触发数据绑定和数据绑定事件,在mutate DOM之前以及数据绑定直接发生之后,用公有的刷新和内存实现这个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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,这就意味着我们可以像下面这个样自定义组件:

1
2
3
4
5
6
7
8
9
10
11
12
<div data-role= "repeater" data-bind= "source: dataSource" >
<script>
     var viewModel = kendo.observable({
         dataSource:   new kendo.data.DataSource({
             transport: {
                 read:  "Customers/Orders" ,
                 dataType:  "json"
             }
         }) 
     });
     kendo.bind(document.body.children, viewModel);
</script>

    以上就是完整的示例了,需要注意的是,当你添加一个项目到数据源的时候,它就会立即反映到中继器组件中。

1
2
3
4
5
6
7
8
9
10
11
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);

>>>Kendo UI Web下载


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值