導入
名前が示すように、エージェントは他の人が物事を行うのを助けることです。 GOFは次のようにプロキシモデルを定義します。
プロキシモード(プロキシ)は、他のオブジェクトがこのオブジェクトへのアクセスを制御するためのプロキシを提供します。
プロキシモードにより、プロキシオブジェクトは特定のオブジェクトの参照を制御できます。プロキシは、ファイル、リソース、メモリ内のオブジェクト、またはコピーが困難なものなど、ほぼすべてのオブジェクトです。
文章
簡単な例を見てみましょう。 Duduがヨーグルトと小さな女の子のバラを送りたいが、彼女の連絡先情報を知らないか、恥ずかしくて叔父にこれらのバラを送るように任せたい場合、叔父はエージェントです(実際、それはかなり良いです、あなたは妻にいくつかの花を差し引くことができます)。
コードコピーは次のとおりです。
//最初に美しさを宣言します
var girl = function(name){
this.name = name;
};
//これはduduです
var dudu = function(girl){
this.girl = girl;
this.sendgift = function(gift){
alert( "hi" + girl.name + "、duduはあなたにギフトを与えます:" + gift);
}
};
//叔父はエージェントです
var proxytom = function(girl){
this.girl = girl;
this.sendgift = function(gift){
(new dudu(girl))。sendgift(ギフト); // duduに花を送ります
}
};
通話方法は非常に簡単です:
コードコピーは次のとおりです。
var proxy = new Proxytom(new Girl( "Yogurt Girl"));
proxy.sendgift( "999 Roses");
実践的な戦い
上記のコードを通して、私は誰もがプロキシモードについて非常に明確だと思います。実際の戦闘を見てみましょう。シンプルなプレイリストがあります。単一の接続をクリックするとき(またはすべてを選択)、接続の下にビデオ曲の紹介と再生ボタンを表示する必要があります。 [再生]ボタンをクリックすると、ビデオが再生されます。リスト構造は次のとおりです。
コードコピーは次のとおりです。
<H1> Dave Matthews Vids </h1>
<p> <span id = "toggle-all">すべてを選択/再選択</span> </p>
<ol id = "vids">
<li> <入力タイプ= "チェックボックス" checked> <a href = "http://new.yahoo.com/videos/---2158073"> Gravedigger </a> </li>
<li> <入力タイプ= "チェックボックス" checked> <a href = "http://new.yahoo.com/videos/---4472739"> me save </a> </li>
<li> <入力タイプ= "チェックボックス" checked> <a href = "http://new.yahoo.com/videos/---- 45286339"> crush </a> </li>
<li> <入力タイプ= "チェックボックス" checked> <a href = "http://new.yahoo.com/videos/--2144530">水を飲まないでください</a> </li>
<li> <入力タイプ= "チェックボックス" checked> <a href = "http://new.yahoo.com/videos/---217241800">面白い</a> </li>
<li> <入力タイプ= "チェックボックス" checked> <a href = "http://new.yahoo.com/videos/---2144532">何と言う</a>
</li>
</ol>
まず以下を分析しましょう。まず、接続aのクリックイベントを監視するだけでなく、「すべて/アンチセレクトを選択」のクリックイベントを監視し、サーバーにビデオ情報を照会し、HTML情報を組み立ててLI要素の最後の位置に表示します。効果は次のとおりです。
次に、Play Connectionのクリックイベントを監視し、クリック後に再生を開始します。効果は次のとおりです。
さて、jqueryなしで、セレクターをカスタマイズしましょう。
コードコピーは次のとおりです。
var $ = function(id){
document.getElementByID(ID)を返します。
};
YahooのJSONサービスはコールバックパラメーターを提供するため、データを受け入れるためにカスタムコールバックを渡します。特定のクエリ文字列アセンブリコードは次のとおりです。
コードコピーは次のとおりです。
var http = {
makerequest:function(ids、callback){
var url = 'http://query.yahooapis.com/v1/public/yql?q='、
sql = 'select * from music.video.id where ids in( "%id%")'、
format = "format = json"、
handler = "callback =" + callback、
script = document.createelement( 'script');
sql = sql.Replace( '%id%'、ids.join( '"、"'));
sql = encodeuricomponent(sql);
url + = sql + '&' + format + '&' +ハンドラー;
script.src = url;
document.body.AppendChild(スクリプト);
}
};
プロキシオブジェクトは次のとおりです。
コードコピーは次のとおりです。
var proxy = {
IDS:[]、
遅延:50、
タイムアウト:null、
コールバック:null、
コンテキスト:null、
//リクエストされたIDとコールバックを設定して、再生中にコールバックをトリガーします
makerequest:function(id、callback、context){
//キューにキューDDに追加します
this.ids.push(id);
this.callback = callback;
this.context = context;
//タイムアウトを設定します
if(!this.timeout){
this.timeout = setimeout(function(){
proxy.flush();
}、this.delay);
}
}、
//リクエストをトリガーすると、http.makerequestが代理責任を使用して呼び出されました
フラッシュ:function(){
// proxy.handlerは、yahooを要求するときのコールバックです
http.makerequest(this.ids、 'proxy.handler');
//データをリクエストした後、proxy.handlerメソッドを実行します(内部に別のコールバックセットがあります)
//タイムアウトとキューをクリアします
this.timeout = null;
this.ids = [];
}、
ハンドラー:function(data){
var i、max;
//単一のビデオのコールバックコール
if(parseint(data.query.count、10)=== 1){
proxy.callback.call(proxy.context、data.query.results.video);
戻る;
}
//複数のビデオのコールバックが呼び出されます
for(i = 0、max = data.query.results.video.length; i <max; i += 1){
proxy.callback.call(proxy.context、data.query.results.video [i]);
}
}
};
ビデオ処理モジュールには、主に3つのサブ機能があります。情報の取得、情報の表示、ビデオの再生:
コードコピーは次のとおりです。
var videos = {
//プレーヤーコードを初期化して再生を開始します
getPlayer:function(id){
return '' +
'<object id = "uvp_fop" approakfullscreen = "true">' +
'<param name = "movie" value = "http://d.yimg.com/m/up/fop/embedflv/swf/fop.swf" /////>' +
'<param name = "flashvars" value = "id = v' + id + '&eid = 1301797&lang = us&enablefullscreen = 0&shareenable = 1" ///>' +
'<param name = "wmode" value = "透過" ///>' +
'<埋め込み' +
'height = "255"' +
'width = "400"' +
'id = "uvp_fop"' +
'Allowfullscreen = "true"' +
'src = "http://d.yimg.com/m/up/fop/embedflv/swf/fop.swf"' +
'Type = "Application/X-ShockWave-Flash"' +
'flashvars = "id = v' + id + '&eid = 1301797&lang = us&ympsc = 4195329&enablefullscreen = 1&shareenable = 1"' +
'///' +
'<// object>';
}、
//情報をスプライスしてコンテンツを表示し、liの追加の下部に表示します
updateList:function(data){
var id、
html = ''、
情報;
if(data.query){
data = data.query.results.video;
}
id = data.id;
html + = '<img src = "' + data.image [0] .url + '" ///>';
html + = '<h2>' + data.title + '<// h2>';
html + = '<p>' + data.copyrightyear + '、' + data.label + '<// p>';
if(data.album){
html + = '<p>アルバム:' + data.album.release.title + '、' + data.album.release.releaseyear + '<br ///>';
}
html + = '<p> <a href = "http://new.music.yahoo.com/videos/--' + id + '">»play </a> <// p>';
info = document.createelement( 'div');
info.id = "info" + id;
info.innerhtml = html;
$( 'v' + id).appendchild(info);
}、
//情報を取得して表示します
getInfo:function(id){
var info = $( 'info' + id);
if(!info){
proxy.makerequest(id、videos.updatelist、videos); //プロキシの責任を実行し、videos.updateListコールバック関数で渡す
戻る;
}
if(info.style.display === "none"){
info.style.display = '';
} それ以外 {
info.style.display = 'none';
}
}
};
これで、クリックイベント用のコードを処理できます。多くの接続があるため、各接続がイベントにバインドされている場合、パフォーマンスに問題があります。そのため、イベントを<ol>要素にバインドし、クリックされた接続がA接続であるかどうかを検出します。クリックされたものがビデオアドレスであることを意味し、その後再生できます。
コードコピーは次のとおりです。
$( 'vids')。onclick = function(e){
var src、id;
e = e || window.event;
src = e.target || E.SRCELEMENT;
//接続でない場合、処理を継続しません
if(src.nodename.touppercase()!== "a"){
戻る;
}
//バブルを停止します
if(typeof e.preventdefault === "function"){
E.PreventDefault();
}
e.ReturnValue = false;
id = src.href.split( ' - ')[1];
//作成されたビデオ情報領域のリンク再生をクリックすると、再生が開始されます
// returnは継続しません
if(src.classname === "play"){
src.parentnode.innerhtml = videos.getPlayer(id);
戻る;
}
src.parentnode.id = "v" + id;
videos.getinfo(id); //これは、初めてクリックするときにビデオ情報を表示するための処理コードです
};
すべてを選択して選択解除するためのコードは似ているので、説明しません。
コードコピーは次のとおりです。
$( 'Toggle-all')。onclick = function(e){
var hrefs、i、max、id;
hrefs = $( 'vids')。getelementsbytagname( 'a');
for(i = 0、max = hrefs.length; i <max; i += 1){
// Play Connectionを無視します
if(hrefs [i] .classname === "play"){
続く;
}
//選択されていないアイテムを無視します
if(!hrefs [i] .parentnode.firstchild.checked){
続く;
}
id = hrefs [i] .href.split( ' - ')[1];
hrefs [i] .parentnode.id = "v" + id;
videos.getinfo(id);
}
};
要約します
プロキシモードは一般に、次の状況に適しています。
1.リモートプロキシ、つまり、異なるアドレススペース内のオブジェクトのローカル表現を提供するため、Webサービスのプロキシクラスのように、異なるアドレススペースにオブジェクトが存在するという事実を非表示にすることができます。
2。仮想エージェントは、必要に応じてオーバーヘッドの高いオブジェクトを作成し、それらを使用して、インスタンス化するのに長い時間がかかる実際のオブジェクトを保存します。たとえば、ブラウザをレンダリングすると、問題を最初に表示し、画像をゆっくりと表示できます(つまり、仮想エージェントが実際の画像を置き換えます。現時点では、仮想エージェントは実際の画像のパスとサイズを保存します。
3。実際のオブジェクトにアクセスするときにアクセス許可を制御するために使用されるセキュリティエージェント。一般に、オブジェクトには異なるアクセス権限が必要です。
4。インテリジェントなガイダンス、実際のオブジェクトが呼び出された場合にのみ、エージェントは他のものを処理します。たとえば、C#のガベージコレクションには、オブジェクトを使用するときに参照があります。オブジェクトに参照がない場合、GCはリサイクルできます。
参照:「ビッグトークデザインパターン」