最近在使用dojo作为项目系统前端开发的第三方库时,遇到了一些问题,由于之前只是单纯的拷贝代码,而未考虑到这些问题,现将这些问题记录下来,并结合DOJO库进行分析,以此系列作为记录,为今后的前端开发积累经验。
Q1、问题描述:
在创建了DOJO 的控件之后,例如统计图表,当更换统计图表中的数据源,重新生成图表的过程中,出现了第一次创建的图表仍存在,且覆盖住了后来生成的新图表(从重叠的文字就能够看出,新的图表已经生成了,但被首次创建的图表所遮挡了)。
PS:我已经在代码中写了关于重新生成图表的时候对已生成的图表进行销毁,但未能成功执行该设计。
<span style="font-family:Times New Roman;font-size:14px;">function drawChart(){
require([
"dijit/registry",
"dojo/dom-construct",
"dojo/dom",
"dojo/domReady!"
],function(dom){
var chart1 = dom.byId("pieChart1");
var site = dijit.byId('selectedbox1').get('displayedValue');</span><span style="font-family:Times New Roman;"></span><span style="font-family:Microsoft YaHei;font-size:14px;"><span style="font-family:Times New Roman;">
if(chart1 != null){
destroyChart();}
else{
pieChart(site); }
});
}</span>
</span>
问题解决思路:学习如何管理Dojo中Widget的生命周期,然后对Widget进行销毁
过程:
1) 认识Widget:大部分的widget都是基于dijit._WidgetBase 和 dijit._Widget 这两个基类创造出来的。
dijit._WidgetBase →→→ dijit._Widget →→→ 自定义Widget
大部分情况下,我们对Widget的管理大多依赖于dijit._WidgetBase提供的方法与属性。
2)Reading Dijit Lifecycle From http://dojotoolkit.org/documentation/tutorials/1.6/understanding_widget/
A、Create Widget:
<span style="font-family:Microsoft YaHei;font-size:14px;"> <span style="font-family:Times New Roman;"> ([widget].constructor());
[widget].postscript();
[widget].create();
[widget].postMixInProperties();
[widget].buildRendering();
[widget].postCreate(); // this is the most important one!
[widget].startup();
</span></span>
postCreate():当所有的属性被定义之后,HTML文档片段中的Widget立即完成创建,这个方法中包含了所有你对调用的Widget对象的设计,用官网文档上的话来描述,这个方法就好像是戏剧表演中的幕布所遮盖住的舞台,待这个方法执行并将所有关于Widget的参数发送到前台的时候,舞台上的幕布就彻底拉开,用户就能看见你设计的内容了。
startup():该方法一般在Widget的DOM节点片段创建完毕,且已经加入到了你的页面文档中去的时候执行,可以将其理解为激活这个Widget组件。在编程实现(非声明式)的Widget定义时,一定不要忘记加入:widget.startup();
B、Tear-down Widget:
[widget].destroy();
[widget].destroyDescendants();
[widget].destroyRecursive();
[widget].destroyRendering();
[widget].uninitialize();
发现问题:通过Firebug单步调试,发现问题出现在判断条件上,if(chart1 != null) 而在HTML 文档中,我直接构造了一个div,而不是在JS代码中生成,所以chart1永远不会为null,因此不会继续执行我调用的Widget销毁函数,从而影响了Widget组件的生命周期管理。
解决方案:1)将生成div的工作交给JS代码实现;
或者 2)将判断条件改为判断 chart1这个div中的innerHTML != “”,即if( chart1.innerHTML != "" )