PDA

View Full Version : [2.2] イベントハンドラの開放



amanoman
9 Mar 2009, 4:23 AM
はじめまして
コンポーネントのonメソッド、addListenerメソッド等でイベントハンドラを追加した場合に、上位コンテナのremoveメソッドでそのコンポーネントが削除された場合は、イベントハンドラも自動的に削除されるのですか?

サンプルコード


<html>
<head>
<title>イベントテスト</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css"/>

<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="../../ext-all.js"></script>
<!--イベントテスト-->
<script type="text/javascript">
Ext.onReady(function() {
//センターにパネルを追加
var addCenterPanel=function() {
var panel=new Ext.Panel({title:'パネル',width:100,height:100,html:'テストです。'});
var center=Ext.getCmp('center');
center.add(panel);
center.doLayout();
//クリックイベントハンドラ追加
panel.el.on('click',function() {alert('クリック!!')});
}
//センターのパネルを全て削除
var removeCenterPanel=function() {
var center=Ext.getCmp('center');
if (center.items.length) {
center.removeAll();
center.doLayout();
}
}
var layout=new Ext.Viewport({
title:'イベントテスト',
layout:'border',
items:[
{
region:'west',
width:150,
items:[
new Ext.Button({
text:'パネル追加',
handler:addCenterPanel
}),
new Ext.Button({
text:'クリア',
handler:removeCenterPanel
})
]
},
{
xtype:'panel',
id:'center',
region:'center',
title:'センターパネル'
}
]
});
layout.render(document.body);

});
</script>
</head>
<body>

</body>
</html>

yuki
9 Mar 2009, 6:38 AM
はじめまして
コンポーネントのonメソッド、addListenerメソッド等でイベントハンドラを追加した場合に、上位コンテナのremoveメソッドでそのコンポーネントが削除された場合は、イベントハンドラも自動的に削除されるのですか?


Ext.Componentのサブクラスであれば、Container側でremove/removeAllが呼ばれた際に、自分自身のdestroyが呼ばれるので(autoDestroyを明示的にfalseにしていると呼ばれませんが)、その際にイベントハンドラもすべて削除されます(ただし、Containerのitemsに含まれていないものについては削除の対象にならないので、独自コンポーネントを作るときには注意が必要です)。

ただ、複数のコンポーネントの組み合わせで作られているコンポーネントでは、実際には上記の仕組みが正常に機能せずにメモリリークを引き起こすケース(特にIEで)がいくつかフォーラム内でも報告されています(2.2.1でかなり改善はしたものの、すべて無くなったわけでないみたいです):


"element orphan" in a "one page one application" web page (http://extjs.com/forum/showthread.php?t=45782)(英語)
Hope for the IE Orphanage (http://extjs.com/forum/showthread.php?t=50400)(英語)


3.0ではこのあたりが抜本的に見直されているとのことなのですが、、、:)

amanoman
9 Mar 2009, 9:01 AM
yukiさん
回答、有難うございます。
私の質問が正しくありませんでした。(すみません)
コンポーネントのon又は、listenerではなく、panel.el.on(…)の場合も、同様にイベントハンドラーが開放されるのですか?
(余談 スレッドの書き込み時刻にus時間が表示されているのですね。:-?)

yuki
9 Mar 2009, 2:52 PM
yukiさん
コンポーネントのon又は、listenerではなく、panel.el.on(…)の場合も、同様にイベントハンドラーが開放されるのですか?

panel.elのイベントハンドラも開放されます。「.el」プロパティについては、コンポーネントが作成される際に自動的にイベントハンドラ(clickとかfocusあたり)が追加されることが多いので、destroyの中で開放されるようになっています。

Ext.Component.destroy

destroy : function(){
if(this.fireEvent("beforedestroy", this) !== false){
this.beforeDestroy();
if(this.rendered){
this.el.removeAllListeners();
this.el.remove();
if(this.actionMode == "container"){
this.container.remove();
}
}
this.onDestroy();
Ext.ComponentMgr.unregister(this);
this.fireEvent("destroy", this);
this.purgeListeners();
}
},



(余談 スレッドの書き込み時刻にus時間が表示されているのですね。:-?)

「アカウント管理」⇒「オプションを編集」⇒「日付と時間のオプション」で表示される日時のタイムゾーンを設定できますよ;)

amanoman
9 Mar 2009, 3:28 PM
yukiさん
おはようございます。
なるほど、ありがとうございます。勉強になりました。
IEのmemory leakの問題は、Ext 3.0に期待します。
(もともと、IEのバグなのに…:-?)


「アカウント管理」⇒「オプションを編集」⇒「日付と時間のオプション」で表示される日時のタイムゾーンを設定できますよ

おっ、時間が日本時間で表示されました。:))