如何通过代码移除声明式AccordionContainer中的子ContentPane?
解决Dojo AccordionContainer声明式布局下的子组件增删问题
首先得纠正你之前的一个核心错误:dom.byId('accContainer')拿到的是DOM元素节点,不是Dojo的AccordionContainer组件实例,所以它根本没有getChildren()方法,调用自然会抛出异常。而registry或dijit.byId返回空,大概率是因为你的代码执行时机太早(组件还没完成初始化),或者你写错了组件的id。
先解决组件实例获取的问题
要操作AccordionContainer,必须先拿到它的Dijit组件实例,正确的做法是:
- 确保你声明式的AccordionContainer确实设置了正确的id,比如:
<div data-dojo-type="dijit/layout/AccordionContainer" id="accContainer"> <div data-dojo-type="dijit/layout/ContentPane" id="bufferPane" title="Buffer Pane"> 面板内容 </div> </div>
- 把操作代码放在组件初始化完成后执行,比如用
dojo/ready包裹:
require(['dijit/registry', 'dojo/ready'], function(registry, ready) { ready(function() { // 这里才能正确拿到组件实例 var accContainer = registry.byId('accContainer'); // 后续的增删操作都在这里写 }); });
移除子组件(比如你的bufferPane)
拿到组件实例后,移除子组件分两步:移除关联 + 销毁组件(可选但推荐,避免内存泄漏):
// 1. 获取要移除的子组件实例(如果有id直接拿) var bufferPane = registry.byId('bufferPane'); // 2. 从AccordionContainer中移除该子组件 accContainer.removeChild(bufferPane); // 3. 彻底销毁子组件(如果不需要再复用的话) bufferPane.destroyRecursive();
如果子组件没有设置id,也可以通过遍历子组件列表找到目标:
var children = accContainer.getChildren(); children.forEach(function(pane) { if (pane.title === 'Buffer Pane') { // 比如通过标题匹配 accContainer.removeChild(pane); pane.destroyRecursive(); } });
添加子组件
要添加新的ContentPane到AccordionContainer,步骤如下:
// 先引入需要的模块 require(['dijit/registry', 'dojo/ready', 'dijit/layout/ContentPane'], function(registry, ready, ContentPane) { ready(function() { var accContainer = registry.byId('accContainer'); // 1. 创建新的ContentPane实例 var newPane = new ContentPane({ title: '新添加的面板', content: '这是新面板的内容' }); // 2. 添加到AccordionContainer中 accContainer.addChild(newPane); // 可选:让新添加的面板自动展开 accContainer.selectChild(newPane); }); });
关键注意点
- 永远不要直接操作DOM节点来增删Dojo布局组件,必须通过组件实例的
addChild/removeChild方法,这样Dojo才会正确处理布局更新和事件绑定。 - 如果是旧版本Dojo(比如1.6及之前),可以用
dijit.byId()代替registry.byId(),用法是一样的。
内容的提问来源于stack exchange,提问作者prashant
相关产品推荐
相关产品推荐

