dojo toolkitやってみる 2
dojoのドキュメントを読んでいたら、dojo/aspectなんていうAOPのためのモジュールがあったので試してみます(Javaではおなじみですね。他の言語でどうなのかよく知りません)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Tutorial: Hello Dojo!</title> </head> <body> <h1 id="greeting">Hello</h1> <h1 id="greetingJa">こんにちは</h1> <!-- load Dojo --> <script src="dojo/dojo.js" data-dojo-config="async: true"></script> <script> require(['dojo/dom','dojo/aspect','dojo/domReady!'], function(dom,aspect){ var signal = aspect.after(/*対象のオブジェクト*/dom, /*function名*/'byId', /*対象のオブジェクトのfunctionが実行された後に実行するfunction=advise*/function(el){ //これは元のfunctionの返り値を返すだけなので特に意味がない。 return el; //例えば下記のように返り値を差し替えることができる //return document.getElementById('greetingJa'); //下記のようにするとまたこのAdvisingFunctionが発動してしまい、スタックを使い果たしてしまう //return dom.byId('greetingJa'); }); var x = dom.byId('greeting'); x.innerHTML += ' World'; }); </script> </body> </html>
上記のような感じで、使う事が出来ます。上で使っているのは、元のfunctionが実行された後に発動するafterですが、その他にbeforeとaroundの計3つのfunctionがこのdojo/aspectパッケージでは提供されています。
after,before,aroundいずれもremoveというfunctionのみを持つオブジェクトが返ります(APIドキュメントではsignalオブジェクトとなっている)。そのremoveを実行する事で、それ以降adviseを無効にする事が出来ます。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Tutorial: Hello Dojo!</title> </head> <body> <h1 id="greeting">Hello</h1> <h1 id="greetingJa">こんにちは</h1> <!-- load Dojo --> <script src="dojo/dojo.js" data-dojo-config="async: true"></script> <script> require(['dojo/dom','dojo/aspect','dojo/domReady!'], function(dom,aspect){ var signal = aspect.after(dom, 'byId', function(el){ return document.getElementById("greetingJa"); }); var x = dom.byId('greeting'); x.innerHTML += ' World'; //adviseを無効化 signal.remove(); x = dom.byId('greeting'); x.innerHTML += ' World'; }); </script> </body> </html>
なお、APIドキュメントを見ると、before,aroundについてはsignalを返すことが明示されていませんが、after同様signalを返します。
beforeは以下のように使います。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Tutorial: Hello Dojo!</title> </head> <body> <h1 id="greeting">Hello</h1> <h1 id="greetingJa">こんにちは</h1> <!-- load Dojo --> <script src="dojo/dojo.js" data-dojo-config="async: true"></script> <script> require(['dojo/dom','dojo/aspect','dojo/domReady!'], function(dom,aspect){ aspect.before(dom, 'byId', function(id){ //明示的に返り値を返さなかった場合、元のfunctionは元の引数で実行される //下記のように配列で値を返してやると、元のfunctionはここで返した値で実行される //return [id + 'Ja']; }); var x = dom.byId('greeting'); x.innerHTML += ' World'; }); </script> </body> </html>
簡単に使えて、面白いですね。