首页 > 代码库 > 【ExtJs学习笔记】Ext.ComponentLoader

【ExtJs学习笔记】Ext.ComponentLoader

最近自己在搭建一个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