標籤:style blog io ar os 使用 java sp div
最近自己在搭建一個ExtJs的前端架構,遇到第一個最棘手的問題就是loader了。
注意,這裡是ComponentLoader,作用是遠程請求一個頁面。而不是Ext.Loader,這個是用於動態載入依賴的。
在解決問題期間,百度、google了很多關於loader的資訊感覺都不是特別有用,這裡我把遇到的問題記錄下來供大家參考
首先我選用的Ext5.0.0的版本,應該算是比較新的版本了
1.關於普通的ComponentLoader不執行script的問題
var panel = Ext.create(‘Ext.panel.Panel‘, { loader: { url: url, scripts: true, autoLoad: true, loadMask: true }});
依照API提供的Demo,我們很容易會寫出以上的代碼,但是在我開發過程中,即使配置scripts:true,也無法執行url頁面裡的js,使用了很多方法也無法解決這個問題。
最後我重寫了控制項的render方法並搭配使用了控制項的update方法,才勉強達到了和scripts:true相同的效果。
代碼如下:
var ctn = Ext.create(‘Ext.container.Container‘, { id: id, title: title, closable: closable == null ? true : closable, layout: ‘border‘, loader: { listeners: { exception: function () { Ext.MessageBox.alert("提示", "頁面載入出現異常,請聯絡管理員") } }, renderer: function (loader, response, active) { var text = response.responseText; loader.getTarget().update(text, true); return true; }, callback: function(loader, success, response, options){ }, url: url, scripts: true, autoLoad: true, loadMask: true }});
如代碼所示,在render裡將請求返回的html通過update方法的第二個參數true來執行js,並且渲染到目標控制項,即ctn裡。
注意,這裡的update相當於將一段可執行檔html執行後,插入目標控制項的子項中,這就是為什麼我這裡要選用container而不選用panel的原因,因為panel會產生panel和panel-body兩個div,所以會影響update的執行,使得遠程請求的html與panel-body同級,造成html不可見的問題。
以上程式碼片段僅供那些遠程請求頁面而script不執行的開發人員替代使用,如果scripts可以自動執行,當然不需要多此一舉了,其實我不明白這是不是5.0的bug,但是我換成4.2貌似也有這個問題,有高手可以解答我這個疑惑那倒是極好的~~
2.遠程請求頁面配置問題
我們都知道到,loader一般用來做菜單和tab的聯動,ctn是一個遠程請求的容器,ctn的父控制項就是tabpanel-child,這個我想大家都能明白。但是,不管ctn如何布局,遠程請求過來的panel都無法根據ctn的layout自動布局。
ctn的代碼在上面已經貼過了,以下是請求頁面panel的代碼
var page = Ext.create(‘Ext.panel.Panel‘, { region: ‘center‘, layout: { type: ‘table‘, columns: 2 }, items:[gridPanel1,gridPanel2]
renderTo: parentId});
是一段很簡單的代碼,ctn的布局是border,按理來說page應該自動擴充佔滿父控制項的寬高,可事實卻沒有。update方法執行了遠程頁面的指令碼之後,通過renderTo把page渲染到ctn上,事實是這樣做會產生布局問題。
由於ctn先被add到tabpanel中了,update雖然先於add執行,但是確實非同步請求,當response時再去渲染,已經無法正確布局了,我也嘗試過updateLayout等,好像都不奏效
最後,在史總的協助下,我多加了一句add語句,而把renderTo去掉,代碼改成
var page = Ext.create(‘Ext.panel.Panel‘, { region: ‘center‘, layout: { type: ‘table‘, columns: 2 }, items:[gridPanel1,gridPanel2]});Ext.getCmp(parentId).add(page);
在代碼執行到遠程子頁面的最後部分時,動態add這個子頁面的panel,我猜想應該是在add源碼中執行的重新布局或是其他方面的功能,所以解決了這個布局問題
我原以為update就是add的功能,事實上卻不是,雖然觀察html元素會發現,雖然元素樹節點都是一樣的。但是通過class不同我就可以猜測,add裡確實執行了重新布局的功能。
只有加了這最後一句,才能把父容器和遠端子頁面關聯起來,是重中之重。
【ExtJs學習筆記】Ext.ComponentLoader