YUI3下widget的plugin开发
最近在嘗試使用YUI3重建ExtFrame框架,使用YUI3做為更佳的UI和JS支持
和ExtJS比,YUI3的UI看起來缺少了足夠的UI控件,但是,YUI3的widget開發更靈活(也更難掌握),YUI3的widget操作更多的基于DOM封裝的Yui Node而不是象ExtJS一樣基于Component,擴展性更靈活
在嘗試將一些邏輯封裝到YUI的DataTable里時遇到了點問題,在ExtJS里,可以直接通過Ext.extend建立Ext.Grid的子件,并向子件里添加屬性和方法,這樣,可以直接調用生成的子件就可以了,但是YUI3的widget在使用Y.Extend后,UI完全沒能被正常渲染出來
經過上論壇咨詢,老外給了些意見,可以使用Y.Base.create來創建子件,但是同樣失敗了,并且有人說子件不能正確渲染可能是widget名稱相關的BUG,但是這可能需要相關開發人員來檢測
然后老外給的意見是使用plugin技術,并給了2個demo網頁,仔細看了后,確實是個不錯的主意,并且嘗試建立自己的plugin后確認,YUI3的plugin確實是個好東西
第一個demo是DataTableFooter,在表格下面增加了一行統計的頁腳,https://github.com/stlsmiths/YUI3-datatable-footer,這個demo確實不錯,但是有點老,里面的DataTable版本其實已經被大幅度修正過了(生成的表格的HTML代碼都和現在版本不一樣,應當是過期版本),很多代碼已經不能在現在版本下正確運行,照著寫了些東西后調試修改了好幾天才能正確運行
第二個demo地址是http://blunderalong.com/yui,里面有很多DataTable的擴展,其中的Paginator Model-View就是翻頁和自動讀取數據的Demo,不過這個demo修改了DataTable內核,一旦引入,頁面上所有DataTable都會自動使用,而不能分開
最后還是以第一個demo為基礎,編寫了2個DataTable的plugin
YUI3的plugin技術,簡單說就是為widget提供一個接口,當widget進行renderUI、syncUI等動作或事件時,plugin可以進行相應并動作
第一個plugin是為DataTable增加checkbox功能
標準的DataTable的checkbox功能,是在創建時為column列增加checkbox列配置
http://yuilibrary.com/yui/docs/datatable/datatable-chkboxselect.html
var table = new Y.DataTable({columns : [{ key: 'select',allowHTML: true, // to avoid HTML escapinglabel: '<input type="checkbox" class="protocol-select-all" title="Toggle ALL records"/>',formatter: '<input type="checkbox" checked/>',emptyCellValue: '<input type="checkbox"/>'},{ key: 'port', label: 'Port No.' },{ key: 'pname', label: 'Protocol' },{ key: 'ptitle', label: 'Common Name' }],data : ports,scrollable: 'y',height : '250px',sortable : ['port','pname'],sortBy : 'port',recordType: ['select', 'port', 'pname', 'ptitle'] }).render("#dtable");之所以編寫checkboxplugin,是因為我在視圖將columns全部通過配置來動態生成,而checkbox寫到配置里是比較麻煩的
修改后的代碼是這樣的:
var table = new Y.DataTable({columns: Y.TableConfig.Get('plan'),scrollable: 'y',height: '200px',data: ports}).plug(Y.DataTablePlugin.CheckboxPlugin).render('#dtable');這樣,通過自己編寫的TableConfig獲取配置的column信息(以后頁面上編寫腳本時無需再編寫繁瑣的column參數),再通過checkboxplugin生成checkbox列
這個寫法和原本Datatable設計有點不同的地方時,在遇到特殊格式時,columns列是通過formatter參數指定格式或格式化的function,而我的設計里不在前臺處理,所以特殊的格式都放到后臺生成數據后使用對應的render來處理
checkboxplugin是這樣寫的
function CheckboxPlugin(config) {CheckboxPlugin.superclass.constructor.apply(this, arguments);};Y.mix(CheckboxPlugin, {NAME: 'checkboxPlugin',NS: 'checkboxplugin',ATTRS: {place: {value: 0,validator: Y.Lang.IsNumber}}});Y.extend(CheckboxPlugin, Y.Plugin.Base, {initializer: function() {var dt = this.get('host');dt.addColumn(checkbox, this.get('place'));dt.delegate("click", function(e) {var checked = e.target.get('checked') || undefined;this.getRecord(e.target).set('select', checked);this.get('contentBox').one('.protocol-select-all').set('checked', false);}, ".yui3-datatable-data .yui3-datatable-col-select input", dt);dt.delegate('click', function(e) {var checked = e.target.get('checked') || undefined;this.data.invoke('set', 'select', checked, { silent: true });this.syncUI();}, '.protocol-select-all', dt);}});Y.namespace('DataTablePlugin');Y.DataTablePlugin.CheckboxPlugin = CheckboxPlugin;可以看到,這樣寫的另一個好處是已經自動將全選事件封裝進去了,無需每個datatable創建后再添加一次此事件
從上面代碼可以看出,plugin的基礎寫法很簡單,主要是在擴展Y.Plugin.Base時,在initialize事件里寫出額外的動作來
在initialize事件里,也可以為host的datatable添加render等事件響應
寫法是:this.afterHostMethod('方法名', 方法)或this.afterHostEvent('事件名', 方法)
也可以使用beforeHostMethod或onHostEvent
一般widget就三個主要事件:renderUI,syncUI,bindUI,方法主要是render等
下面是我參考編寫的DataTableFooter,用來翻頁的,不過這個plugin不能單獨工作,需要和DataReaderPlugin協調(還沒寫好),目前也就完成了UI部分
function DataTablePageBar(config) {DataTablePageBar.superclass.constructor.apply(this, arguments);};Y.mix(DataTablePageBar, {NAME: 'dataTablePageBar',NS: 'pageBarPlugin',ATTRS: {place: {value: 0,validator: Y.Lang.IsNumber},fixed: {value: false,validator: YLang.isBoolean},info: {value: {pagecount: 1,currentpage: 1,totalcount: 1},setter: function(val) {this._tfootThNode.one('.page').set('text', '第' + val.currentpage + '頁/共' + val.pagecount + '頁 ' + val.totalcount + '條記錄');return val;}}}});Y.extend(DataTablePageBar, Y.Plugin.Base, {_tfootContainer: null,_tfootNode: null,_tfootTrNode: null,_tfootThNode: null,initializer: function() {this.afterHostMethod("render", this.renderPluginUI);},renderPluginUI: function() {var dt = this.get(HOST),hdg = this.get(FOOT_HDG),tfootParent = dt._parentNode;if (dt.get("contentBox").one(".yui3-datatable-y-scroller-container")) {this._tfootNode = dt.get("contentBox").one(".yui3-datatable-y-scroller-container").appendChild(YCreate("<table width='100%'/>")).appendChild(YCreate("<tfoot/>"));}else {this._tfootNode = dt.get("contentBox").one(".yui3-datatable-table").appendChild(YCreate("<tfoot/>"));}this._tfootTrNode = this._tfootNode.appendChild(YCreate("<tr/>"));this._tfootThNode = this._tfootTrNode.appendChild(YCreate("<th colSpan='" + dt.get('columns').length + "'/>"));this._tfootThNode.addClass('yui3-datatable-ftth');this._tfootThNode.appendChild(YCreate('<span><a class="firstpage" href="#"><img src="../image/page-first.gif" /></a></span><span><a class="prevpage" href="#"><img src="../image/page-prev.gif" /></a></span><span><a class="nextpage" href="#"><img src="../image/page-next.gif" /></a></span><span><a class="lastpage" href="#"><img src="../image/page-last.gif" /></a></span><span class="page"></span><span class="jump">跳轉到第<input type="text" style="width:20px" maxlength="3">頁<a class="jumppage" href="#"><image src="../image/go.gif" /></a></span>'));}});說明:YCreate就是Y.Node.Create,另外還有行代碼?Y.DataTablePlugin.PageBarPlugin = DataTablePageBar;在最后
中間創建tfoot的代碼,原來那個demo已經太老完全不對,通過檢查生成的html后修改成為現在的樣子,有無scroll時寫法是不一樣的
?最后效果圖
轉載于:https://www.cnblogs.com/zuxOK/archive/2012/11/09/2762106.html
總結
以上是生活随笔為你收集整理的YUI3下widget的plugin开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCL快速入门教程
- 下一篇: 网络相关配置,SSH服务,bash, 元