日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用ExtJs创建新的UI控件(转)

發布時間:2025/7/25 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用ExtJs创建新的UI控件(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

組合或擴展

當創建一個新類,往往要作出這么的一個選擇:要么擁有某個工具類的實例來扮演首要的角色,要么擴展那個類。

使用ExtJs過程中,推薦從最靠近的基類開始擴展,實現所需的功能即可。這是因為Ext提供的自動生存周期引入了自動渲染的機制、自動大小調整和承擔接受來自布局管理器的UI組件布局調控,還有在容器(Container)中自動銷毀的功能。

組織一個新類,它就是ExtJs的類,實現起來是很方便的,這就會導致了Container→Component層次的形成,相比較,新類擁有一個ExtJs類的話,必須從外圍對其渲染和組織。

The Template method Pattern模板方法模式

Ext Js的Component的繼承層次采用Template Method pattern(模板方法模式)來委派給子類,交由子類來負責其特定的行為。

其意義在于,繼承鏈中的每個子類得以在,組件生存周期的某個階段內,“提交(contribute)”額外的邏輯功能。這樣每一個類擁有屬于其自身的行為;其他類加入自己的行為時也不會相互造成影響。

其中一個例子是render(渲染)函數。render函數不能夠被覆蓋,應該是一層一層地在各子類的實現中加入onRender方法,那么render函數就會在執行的時候把各onRender方法訪問調用。每一個onRender方法必須調用其父類的onRender方法繼而再“埋頭處理(contribute)”自己(子類)的邏輯部分。

下面的圖例演示了模板方法onRender的機能過程。

render是由容器的布局管理器(Container’s layout manager)負責調用。該方法的實現不能被“沖掉(overridden)”,它是由Ext基類提供的。this.onRender表示當前子類所寫的實現(如有提供的話)。它會訪問父類的版本、父類的版本又會調用父、父類的版本……最終,每個類完成了其功能,render函數的返回值對生存周期進行控制。

在ExtJS組件(Component)生存周期中,提供了若干有意義的模板方法以實現類特定的邏輯功能。

強調: 當編寫子類時,模板方法應在實例化的過程中調用,屬于生存周期內的一部分的動作,而不應是事件的一部分。事件有可能會由handler掛起,或中止。

以下是Component子類都可享有的模板方法:

  • onRender
允許渲染期間加入特定的行為。父類的onRender被調用后,可以確定組件的Element元素。可以在此階段中執行剩余DOM任務以完成結構上的控制(HTML結構)。
  • afterRender
允許渲染完成后加入特定的行為。此階段的組件元素會根據配置的要求(configuartion)設置樣式,會引入已配置的CSS樣式名稱所指定的樣式名稱,并會配置可見性(visibility)和配置可激活(enable)情況。
  • onShow
允許在顯示組件的同時加入特定的行為。父類的onShow執行過后,Componenet將會顯示。
  • onHide
允許在隱藏組件的同時加入特定的行為。父類的onHide執行過后,Componenet將會隱藏。
  • onDisable
允許在禁用組件的同時加入特定的行為。父類的onDisable執行過后,Componenet將會禁用。
  • onEnable
允許在激活組件的同時加入特定的行為。父類的onEnable執行過后,Componenet將會激活啟用。
  • onDestroy
允許在銷毀組件的同時加入特定的行為。父類的onDestroy執行過后,Componenet將會被銷毀。

Ext組件類的各層次中的均有其自身的模板方法,我們可以打開來看看,這些都是根據自身不同的需求而作出的設計。

提示: 當調用父類的模板方法時,最簡潔的方法就是使用Function.apply,保證所有的參數都可以接受得到,傳送給那個模板方法:

Ext.ux.Subclass.superclass.onRender.apply(this, arguments);

要擴展哪個類

選擇適合的類來擴展不但要考慮基類提供哪些功能,而且對性能方面也要著重考慮。無論有多少個UI控件被渲染或調控,Ext.Panel常常就是被衍生(extend)的對象。

Panel類擁有許多的能力:

  • Border(軀干)
  • Header(頭部)
  • Header工具條
  • Footer(底部)
  • Footer按鈕
  • Top toolbar(頂部工具條)
  • Bottom toolbar(底部工具條)
  • 承托和管理子組件

如果這些派不上用場,那使用Panel便是資源浪費。

Component(組件類)

如果要求的UI控件不需要其他的細節的控件,也就是,僅僅是封裝某部分的HTML元素的話,那么可取的擴展對象就是Ext.BoxComponentExt.Component。如果再縮窄一步,我不需要聽憑父容器提供的大小調控功能,那么使用Ext.Component就可以了。

強調: Component類并不會內省而得知哪一種元素作為holder。因此為了創建所需的元素(Element),應設定autoEl的配置項。

例如,要把一張圖片封裝為Component,我們于是乎這樣定義:

Ext.ux.Image = Ext.extend(Ext.Component, {autoEl: {tag: 'img',src: Ext.BLANK_IMAGE_URL,cls: 'tng-managed-image'},// Add our custom processing to the onRender phase. // We add a ‘load’ listener to our element.onRender: function() {Ext.ux.Image.superclass.onRender.apply(this, arguments);this.el.on('load', this.onLoad, this);},onLoad: function() {this.fireEvent('load', this);},setSrc: function(src) {this.el.dom.src = src;} });

這是一個可封裝圖片的Ext Component類,可參與非箱子方寸模型(non box-sizing)的布局。

BoxComponent

如果要求的UI控件不需要其他的細節的控件,也就是,僅僅是封裝某部分的HTML元素的話,還要聽憑布局管理器提供的大小尺寸、布局的調控,那么這個的擴展對象就是Ext.BoxComponent。

例如,假設一個Logger類打算是簡單地顯示log信息,就必須嵌入某種布局的風格,例如插入到一個layout:’fit’窗體,可以這樣定義:

Ext.ux.Logger = Ext.extend(Ext.BoxComponent, {tpl: new Ext.Template("<li class='x-log-entry x-log-{0:lowercase}-entry'>","<div class='x-log-level'>","{0:capitalize}","</div>","<span class='x-log-time'>","{2:date('H:i:s.u')}","</span>","<span class='x-log-message'>","{1}","</span>","</li>"),autoEl: {tag: 'ul',cls: 'x-logger'},onRender: function() {Ext.ux.Logger.superclass.onRender.apply(this, arguments);this.contextMenu = new Ext.menu.Menu({items: [new Ext.menu.CheckItem({id: 'debug',text: 'Debug',checkHandler: Ext.ux.Logger.prototype.onMenuCheck,scope: this}), new Ext.menu.CheckItem({id: 'info',text: 'Info',checkHandler: Ext.ux.Logger.prototype.onMenuCheck,scope: this}), new Ext.menu.CheckItem({id: 'warning',text: 'Warning',checkHandler: Ext.ux.Logger.prototype.onMenuCheck,scope: this}), new Ext.menu.CheckItem({id: 'error',text: 'Error',checkHandler: Ext.ux.Logger.prototype.onMenuCheck,scope: this})]});this.el.on('contextmenu', this.onContextMenu, this, {stopEvent: true});},onContextMenu: function(e) {this.contextMenu.logger = this;this.contextMenu.showAt(e.getXY());},onMenuCheck: function(checkItem, state) {var logger = checkItem.parentMenu.logger;var cls = 'x-log-show-' + checkItem.id;if (state) {logger.el.addClass(cls);} else {logger.el.removeClass(cls);}},debug: function(msg) {this.tpl.insertFirst(this.el, ['debug', msg, new Date()]);this.el.scrollTo("top", 0, true);},info: function(msg) {this.tpl.insertFirst(this.el, ['info', msg, new Date()]);this.el.scrollTo("top", 0, true);},warning: function(msg) {this.tpl.insertFirst(this.el, ['warning', msg, new Date()]);this.el.scrollTo("top", 0, true);},error: function(msg) {this.tpl.insertFirst(this.el, ['error', msg, new Date()]);this.el.scrollTo("top", 0, true);} });

接著是CSS:

.x-logger {overflow: auto; } .x-log-entry .x-log-level {float: left;width: 4em;text-align: center;margin-right: 3px; } .x-log-entry .x-log-time {margin-right: 3px; } .x-log-entry .x-log-message {margin-right: 3px; } .x-log-debug-entry, .x-log-info-entry, .x-log-warning-entry, .x-log-error-entry {display: none; }.x-log-show-debug .x-log-debug-entry { display: block } .x-log-show-info .x-log-info-entry { display: block } .x-log-show-warning .x-log-warning-entry { display: block } .x-log-show-error .x-log-error-entry { display: block }.x-log-debug-entry .x-log-level { background-color: #46c } .x-log-info-entry .x-log-level { background-color: green } .x-log-warning-entry .x-log-level { background-color: yellow } .x-log-error-entry .x-log-level { background-color: red }

我們吧log的信息的HTML列表均放置在一個布局中。我們在onRender的階段加入處理,使得右鍵菜單可以根據CSS樣式類的名稱操控logged條目的可見性。位于該層次的對象還提供了特別的模板方法:

  • onResize
此時此刻,BoxComponent的大小已經發生變化,此時可執行剩余的任務。
  • onPosition
此時此刻,BoxComponent的定位已經發生變化,此時可執行剩余的任務。

Container(容器類)

如果要求的UI控件將用于承載(Contain)其他UI元素在其身上,但并不需要前文提及到的Ext.Panel那么多的功能,為避免臃腫,應采用Ext.Container容器類來繼承。同樣地,autoEl指定元素的配置項亦必不可少,將用于容器在某個元素之上進行渲染。同樣,在視覺控制方面,滾動條是否顯示方面(即overflow屬性),用戶都可以使用Style配置項,或容器元素的class屬性的兩種方式進行CSS樣式制定。

注意: 對于Container層次,不要忘記哪種布局類是被用于渲染和調控子組件的。

示例中的類封裝了條件命令的查詢,允許用戶對Store基于測試字段的數據篩選。除了功能上的封裝外,還把查詢任務作統一布局,封裝在一個可控類中,可方便從容器身上自動添加或移除查詢的條目,靈活性更高:

Ext.ux.FilterCondition = Ext.extend(Ext.Container, {layout: 'table',layoutConfig: {columns: 7},autoEl: {cls: 'x-filter-condition'},Field: Ext.data.Record.create(['name', 'type']),initComponent: function() {this.fields = this.store.reader.recordType.prototype.fields;this.fieldStore = new Ext.data.Store();// Create a Store containing the field names and types // in the passed Store.this.fields.each(function(f) {this.fieldStore.add(new this.Field(f))}, this);// Create a Combo which allows selection of a fieldthis.fieldCombo = new Ext.form.ComboBox({triggerAction: 'all',store: this.fieldStore,valueField: 'name',displayField: 'name',editable: false,forceSelection: true,mode: 'local',listeners: {select: this.onFieldSelect,scope: this}});// Create a Combo which allows selection of a testthis.testCombo = new Ext.form.ComboBox({triggerAction: 'all',store: ['<', '<=', '=', '!=', '>=', '>']});// Inputs for each type of field. Hidden and shown as necessarythis.booleanInput = new Ext.form.Checkbox({hideParent: true,hidden: true});this.intInput = new Ext.form.NumberField({allowDecimals: false,hideParent: true,hidden: true});this.floatInput = new Ext.form.NumberField({hideParent: true,hidden: true});this.textInput = new Ext.form.TextField({hideParent: true,hidden: true});this.dateInput = new Ext.form.DateField({hideParent: true,hidden: true});this.items = [ this.fieldCombo, this.testCombo, this.booleanInput, this.intInput, this.floatInput, this.textInput, this.dateInput];Ext.ux.FilterCondition.superclass.initComponent.apply(this, arguments);},onFieldSelect: function(combo, rec, index) {this.booleanInput.hide();this.intInput.hide();this.floatInput.hide();this.textInput.hide();this.dateInput.hide();var t = rec.get('type');if (t == 'boolean') {this.booleanInput.show();this.valueInput = this.booleanInput;} else if (t == 'int') {this.intInput.show();this.valueInput = this.intInput;} else if (t == 'float') {this.floatInput.show();this.valueInput = this.floatInput;} else if (t == 'date') {this.dateInput.show();this.valueInput = this.dateInput;} else {this.textInput.show();this.valueInput = this.textInput;}},getValue: function() {return {field: this.fieldCombo.getValue(),test: this.testCombo.getValue(),value: this.valueInput.getValue()};} });

此類管理了其包含的輸入字段,可以精確的布局-大小調整,外補丁等等——都是通過CSS樣式分配到元素身上這樣來起作用的。

位于該層次的對象還提供了特別的模板方法:

  • onBeforeAdd
當添加新的子組件的時候,就會調用該方法。這時會有新組件作為參數傳入,或者可修改它,或者以特別的方式準備好Container。返回false表示終止添加的操作。

Panel

如果所需的UI控件要求頭部、底部、或工具條之類的元素,那么Ext.Panel就是一個很不錯的類給予繼承了。

注意: Panel是容器的一種,不要忘記哪種布局類是被用于渲染和調控子組件的。

通常Ext.Panel所實現的類會有很高的程序結合性,一般用于與其他UI控件協調使用(通常Containers,或表單字段),并對其有特定配置的布局風格。另外,要對在其內的組件提供操作的命令,可以從tbar(頂部工具欄),bbar(底部工具欄)的兩方面設置加以控制。

Field

如果所需的UI控件要求為用戶交互,可以把程序的數據顯示給用戶,或修改進而發生給服務器的功能,那么要被擴展的類應該是Ext.form.TextField,或Ext.Form.NumberField。另外,如果要求輪換按鈕(Trigger button),以備鍵盤按鍵的輪換,那就是Ext.form.TriggerField

位于該層次的對象還提供了特別的模板方法:

  • onFocus:input輸入框得到焦點后即會觸發該方法的執行。
  • onBlur:input輸入框失去焦點后即會觸發該方法的執行。

什么時候不需要子類

有些時候,濫用子類無異于“殺雞用牛刀”。在一些特定應用場合,某個現有的類它的方法被添加、被重寫,是由這個類的構造器實例化過程中依靠參數傳入的。

轉載于:https://www.cnblogs.com/ibravias/archive/2011/08/11/2134594.html

總結

以上是生活随笔為你收集整理的使用ExtJs创建新的UI控件(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。