我们前阶段在extjs下遇到了一个非常棘手的问题。
问题描述:
我们项目的第一页是一个Grid,Grid上方有个fieldContainer,fieldContainer中有1个超链接,然后右边是一个Combobox,然后我们在chrome25/26上发现,不管这样整个fieldContainer始终收缩成1条直线。然后很快我们就猜想,这是因为fieldContainer的宽度被收缩到0所致,后来具体我们用了一整天的时间进行了调试,终于发现了根本原因和解决方法。也就是这篇博客提供的内容。当然了,这博客记载了我调试的全部过程,如果嫌特别长的话,读者可以直接看下方我高亮显示的结论。
话题1:在extjs BoxLayout下,如何使用width的配置项
事实上,我们有3种方式
width:'50%'
width:100
width:'100px'
我们现在需要深入研究,在这3种使用方式下,容器宽度是如何最终被计算出来的。
因为使用HBoxLayout,所以我们把断点打在如下位置:
方式1:使用百分比代表宽度
也就是以下方式:
用这种方式下,percentageWidth的值是true:
所以它执行了以下的代码:
然后我们到第46702行:
这里,从第46703行可以看出来,hasPixelWidth返回了false,这个和我们所设想的一致,因为我们只传递了一个百分比而不是一个像素的具体值,所以,它最后执行到了第46716行,也就是说,现在这个widthModel是被计算出来的。
最终我们观察现在的widthModel如下:
这个和我们所设想的一致,因为我们的值是一个百分比而不是一个固定的像素值,所以这个当前的widthModel的名字叫“calculated", 表示我们使用了一个用计算得出来的宽度模型。
方法2:使用固定的整数值代表宽度
也就是以下方式:
在这种方式下,percentageWidth的值为false,我们直接跳到第46702行:
在这个代码段中我们可以看到,第46703行的hasPixelWidth返回的值为true,这刚好和我们的设想吻合,因为现在的宽度值是一个具体的定值,所以现在宽度模型看上去如下:
最终,这个也很好的匹配了我们的猜想,因为我们提供的是精确的数值”200“,所以布尔变量”calculated' 的取值为false,而且因为我们提供了实际值,所以现在这个widthModel为“configured",因为我们通过配置来给出了一个合理的宽度模型。
方法3:使用一个像素值加单位,但是用单引号包括它来使用宽度
也就是用以下方式:
在这种方式下,percentageWidth依然被设置为false,我们直接跳到46702行:
在这里,我们惊讶的发现,第46703行的hasPixelWidth居然返回false:
这个太出人意料了,不是吗?所以我们总结的结论是:只用用一个纯数值来表示的宽度,extjs框架才会把它当做一个像素值,然后我们把它包含了在单引号并且加了单位之后,extjs就不会把它当做一个像素值了,所以这就是width:100 和 width:'100px'的区别。
所以,最后的宽度模型是:
它也最终和我们的猜想匹配,因为我们提供了精确的值"200px",所以布尔变量"calculated'的取值为false,但是虽然我们提供了实际的数据,但是它并不被框架当做具体的像素值,所以现在宽度模型被设置为了"shrinkWrap,也就是说最终当调用initComponent()的时候,整个容器会收缩。
所以最终结论罗列在这里:
结论1: 三种不同的宽度的设置方法对应了三种不同的宽度模型的名字
width:'50%' -> 宽度模型:calculated
width:100 -> 宽度模型:configured
width:'100px'->宽度模型:shrinkWrap
结论2:width:100和width:'100px'的区别在于,如果使用的是整数,那么extjs会吧值当做一个pixelWidth,然后变量hasPixelWidth被设置为true,但是如果我们使用'100px',那么extjs不会吧这个值当做一个pixelWidth,然后hasPixelWidth被设置为false。
话题2:许多extjs的时间都采用了width:'100px"的风格,那么这种风格何时起作用呢?
事实上,如果我们仔细看代码的第46682行,我们就可以看出端倪来了:
这里我们可以看出来,虽然shrinkWrap被设置为true,width="45px",typeofWidth="string"被设置为true,但是topLevel被设置为false,所以在46682行被断开了,但是如果我们设置topLevel为true的话,就可以正常的走这些流程了。
所以我们的结论是:
如果我们使用width:'45px'这种风格的话,我们必须保证容器在组件树的顶层。