BrowserManager は、ブラウザとアプリケーションとの間のプロキシとして機能するシングルトンクラスです。JavaScript の document.location プロパティへのアクセスに似た、ブラウザのアドレスバーの URL へのアクセスを提供します。ブラウザの URL が変化すると、BrowserManager にイベントが通知されます。その後で、URL の変更、イベントへの応答、またはイベントのブロックを行うことができます。
BrowserManager への参照を取得するには、getInstance() メソッドを呼び出します。このメソッドは、IBrowserManager を実装するマネージャの現在のインスタンスを返します。その後で、setTitle() および setFragment() などのマネージャのメソッドを呼び出すことができます。
マネージャのイベントを待ち受けることもできます。イベントは、browserURLChange、urlChange、および applicationURLChange です。それらのイベントについては、BrowserManager イベントについてで説明します。
マネージャのプロパティにアクセスすることもできます。マネージャのプロパティには、ブラウザの現在のタイトル、および完全な URL とその各部分である fragment および base が保存されます。これらのプロパティは読み取り専用ですが、setTitle() および setFragment() などのマネージャのメソッドを使用して、一部のプロパティの値を設定できます。
通常は、アプリケーションの初期化時に getInstance() メソッドを呼び出します。このメソッドは、シングルトン BrowserManager のインスタンスを返します。その後で、browserURLChange イベントのイベントリスナーを登録します。このイベントは、ユーザーがブラウザの「戻る」または「進む」ボタンをクリックしたときに送出されます。最後に、init() メソッドを呼び出して BrowserManager を初期化します。init() メソッドの 1 番目のパラメータはデフォルトのフラグメントを定義し、2 番目のパラメータは現在のページのタイトルを定義します。
次の例では、BrowserManager をインスタンス化し、browserURLChange イベントを待ち受けるために parseURL() メソッドを登録して、空白のフラグメントをデフォルトのフラグメントとして init() メソッドを呼び出します。ページのタイトルの値を「Test Deep Linking」に設定します。
private function initApp():void {
browserManager = BrowserManager.getInstance();
browserManager.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE, parseURL);
browserManager.init("", "Test Deep Linking");
}
また、BrowserManager クラスの init() メソッドを呼び出すと、履歴管理が無効になり、現在の URL が BrowserManager のプロパティとして取得されます。
init() メソッドのデフォルトのフラグメントとしてある値を設定した場合、URL が変更されると、そのデフォルトのフラグメントを持つ URL がブラウザの履歴に追加されます。このように、ユーザーが「戻る」ボタンをクリックするか、または他の方法でブラウザの履歴からこのページにアクセスした場合、このフラグメントが使用されます。また、URL がシャープ記号(#)で終わる場合に、BrowserManager はデフォルトのフラグメントを返します。
BrowserManager の setFragment() メソッドを使用して、ブラウザのアドレスバーの URL を更新します。変更できるのは URL のフラグメントのみです。サーバー、プロトコル、またはポート番号など、URL の基本部分は変更できません。
setFragment() メソッドを使用して URL を変更すると、applicationURLChange イベントがトリガされます。
次の例では、TabNavigator コンテナでアクティブなパネルを変更するたびにブラウザの URL を更新します。また、applicationURLChange がトリガされるたびに、現在の URL および前の URL の記録を保存します。
<?xml version="1.0" encoding="utf-8"?>
<!-- deeplinking/UpdateURLExample.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
historyManagementEnabled="false"
creationComplete="init();"
>
<mx:Script>
<![CDATA[
import mx.events.BrowserChangeEvent;
import mx.managers.IBrowserManager;
import mx.managers.BrowserManager;
import mx.utils.URLUtil;
private var browserManager:IBrowserManager;
private function init():void {
browserManager = BrowserManager.getInstance();
browserManager.addEventListener(BrowserChangeEvent.APPLICATION_URL_CHANGE,
logURLChange);
browserManager.init("", "Welcome!");
}
public function updateTitle(e:Event):void {
browserManager.setTitle("Welcome " + ti1.text + " from " + ti2.text + "!");
}
private function updateURL(event:Event):void {
var s:String = "panel=" + event.currentTarget.selectedIndex;
browserManager.setFragment(s);
}
private function logURLChange(event:BrowserChangeEvent):void {
ta1.text += "APPLICATION_URL_CHANGE event:\n";
ta1.text += " url: " + event.url + "\n"; // Current URL in the browser.
ta1.text += " prev: " + event.lastURL + "\n"; // Previous URL.
}
]]>
</mx:Script>
<mx:TabNavigator id="tn" width="300" change="updateURL(event)">
<mx:Panel label="Personal Data">
<mx:Form>
<mx:FormItem label="Name:">
<mx:TextInput id="ti1"/>
</mx:FormItem>
<mx:FormItem label="Hometown:">
<mx:TextInput id="ti2"/>
</mx:FormItem>
<mx:Button id="b1" click="updateTitle(event)" label="Submit"/>
</mx:Form>
</mx:Panel>
<mx:Panel label="Credit Card Info">
<mx:Form>
<mx:FormItem label="Type:">
<mx:ComboBox>
<mx:dataProvider>
<mx:String>Visa</mx:String>
<mx:String>MasterCard</mx:String>
<mx:String>American Express</mx:String>
</mx:dataProvider>
</mx:ComboBox>
</mx:FormItem>
<mx:FormItem label="Number:">
<mx:TextInput id="ccnumber"/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
<mx:Panel label="Check Out">
<mx:TextArea id="ta2" text="You must agree to all the following conditions..."/>
<mx:CheckBox label="Agree"/>
</mx:Panel>
</mx:TabNavigator>
<mx:TextArea id="ta1" width="580" height="400"/>
</mx:Application>
2 番目のパネルをクリックすると change イベントがトリガされるため、Flash Player が updateURL() メソッドを呼び出します。このメソッドは、ブラウザのアドレスバーの URL を変更する setFragment() メソッドを呼び出します。パネルを切り替えていくと、ブラウザのアドレスバーにある次の URL は
http://localhost:8100/devapps/code/deeplinking/FragmentExample.html#panel=1
その後に次のように変更されます。
http://localhost:8100/devapps/code/deeplinking/FragmentExample.html#panel=2
その後に次のように変更されます。
http://localhost:8100/devapps/code/deeplinking/FragmentExample.html#panel=0
Flex アプリケーションでブラウザのアドレスバーの URL が変更されるたびに、Flash Player から applicationURLChange イベントが送出されます。この例では、このイベントオブジェクトのプロパティである前の URL と現在の URL を記録します。
ブラウザのアドレスバーの URL を変更しても、ディープリンク機能が提供されるとは限りません。例えば、ブックマークに登録されている、パネルを特定する URL をロードしても、そのパネルではアプリケーションが起動されません。アプリケーションの状態が URL を反映するように、URL を解析するコードをアプリケーションに追加する必要があります。
この場合、browserURLChange イベントのリスナーを追加します。そのリスナーで、URL を解析し、その結果に基づいてアプリケーションの状態を設定します。例えば、URL が panel=2 のフラグメントを含む場合、選択されたインデックス 2 を現在のパネルに設定するコードを記述します。
browserURLChange イベントは、アプリケーションが初めてロードされたときにはトリガされません。このため、アプリケーションの creationComplete イベントを使用した起動時に URL をチェックし、画面上でのアプリケーションのレンダリングが終了する前に URL の解析をトリガする必要もあります。
Accordion の selectedIndex プロパティを URL の index の値に設定する簡単な例を次に示します。次の例に示すように、URL の index フラグメントの値を設定して、このアプリケーションを要求します。
http://www.myurl.com/InitFrag.html#index=1
アプリケーションの起動時に、index フラグメントの値に対応するパネルに Accordion を開きます。
<?xml version="1.0" encoding="utf-8"?>
<!-- deeplinking/InitFrag.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
historyManagementEnabled="false"
creationComplete="init(event);"
>
<mx:Script>
<![CDATA[
import mx.managers.BrowserManager;
import mx.managers.IBrowserManager;
import mx.events.BrowserChangeEvent;
import mx.utils.URLUtil;
private var bm:IBrowserManager;
private function init(e:Event):void {
bm = BrowserManager.getInstance();
bm.init("", "Welcome!");
parseURL(e);
}
[Bindable]
private var indexFromURL:int;
private function parseURL(e:Event):void {
var o:Object = URLUtil.stringToObject(bm.fragment);
indexFromURL = o.index;
}
]]>
</mx:Script>
<mx:Accordion selectedIndex="{indexFromURL}">
<mx:VBox label="Panel 1">
<mx:Label text="Accordion container panel 1"/>
</mx:VBox>
<mx:VBox label="Panel 2">
<mx:Label text="Accordion container panel 2"/>
</mx:VBox>
<mx:VBox label="Panel 3">
<mx:Label text="Accordion container panel 3"/>
</mx:VBox>
</mx:Accordion>
</mx:Application>
次の例では、URL の更新の例を拡張しています。起動時に URL を読み込み、panel フラグメントの値に応じて、1 番目、2 番目、または 3 番目のパネルにアプリケーションを開きます。また、開かれているパネルに基づいて HTML ページのタイトルを設定します。
<?xml version="1.0" encoding="utf-8"?>
<!-- deeplinking/TabNavExample.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp()"
historyManagementEnabled="false"
height="250"
width="500"
>
<mx:Script>
<![CDATA[
import mx.events.BrowserChangeEvent;
import mx.managers.IBrowserManager;
import mx.managers.BrowserManager;
import mx.utils.URLUtil;
public var browserManager:IBrowserManager;
private function initApp():void {
browserManager = BrowserManager.getInstance();
browserManager.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE, parseURL);
browserManager.init("", "Shipping");
}
private var parsing:Boolean = false;
private function parseURL(event:Event):void {
parsing = true;
var o:Object = URLUtil.stringToObject(browserManager.fragment);
if (o.view == undefined)
o.view = 0;
tn.selectedIndex = o.view;
browserManager.setTitle((tn.selectedIndex == 0) ? "Shipping" : "Receiving");
tn.validateNow();
var details:Boolean = o.details == true;
if (tn.selectedIndex == 0)
shipDetails.selected = details;
else
recvDetails.selected = details;
parsing = false;
}
private function updateURL():void {
if (!parsing)
callLater(actuallyUpdateURL);
}
private function actuallyUpdateURL():void {
var o:Object = {};
var t:String = "";
if (tn.selectedIndex == 1) {
t = "Receiving";
o.view = tn.selectedIndex;
if (recvDetails.selected)
o.details = true;
} else {
t = "Shipping";
o.view = tn.selectedIndex;
if (shipDetails.selected)
o.details = true;
}
var s:String = URLUtil.objectToString(o);
browserManager.setFragment(s);
browserManager.setTitle(t);
}
]]>
</mx:Script>
<mx:TabNavigator id="tn" change="updateURL()" width="300">
<mx:Panel label="Shipping">
<mx:CheckBox id="shipDetails" label="Show Details" change="updateURL()" />
</mx:Panel>
<mx:Panel label="Receiving">
<mx:CheckBox id="recvDetails" label="Show Details" change="updateURL()" />
</mx:Panel>
</mx:TabNavigator>
</mx:Application>
この例には、大きな欠点が 1 つあります。この例では、現在のビューにないパネルの状態が「記憶」されません。ブックマークをコピーして新しいブラウザで開く場合、最後に表示していたビューと、そのビューの CheckBox の状態は保持されます。しかし、表示されていなかった他のビューの CheckBox は、元の値(チェックがオフの状態)にリセットされます。この問題を解決するための方法がいくつかあります。詳しくは、ディープリンクとナビゲータコンテナの併用を参照してください。
BrowserManager は、次のタイプの BrowserChangeEvent イベントをトリガします。
上記の change イベントは、次のアクションによってトリガできます。
urlChange イベントは、applicationURLChange または browserURLChange イベントがトリガされたとき、常にトリガされます。
DataGrid コントロールの change イベントのプロパティの例を次に示します。ComboBox コントロールで新しい値を選択すると、applicationURLChange イベントをトリガできます。ブラウザの「戻る」および「進む」ボタンを使用すると、browserURLChange イベントをトリガできます。いずれの場合も、urlChange イベントもトリガします。
<?xml version="1.0" encoding="utf-8"?>
<!-- deeplinking/URLChangeLogger.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
historyManagementEnabled="false"
creationComplete="init();"
>
<mx:Script>
<![CDATA[
import mx.managers.BrowserManager;
import mx.managers.IBrowserManager;
import mx.events.BrowserChangeEvent;
private var bm:IBrowserManager;
private function init():void {
bm = BrowserManager.getInstance();
bm.addEventListener(BrowserChangeEvent.APPLICATION_URL_CHANGE, doEvent);
bm.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE, doEvent);
bm.addEventListener(BrowserChangeEvent.URL_CHANGE, doEvent);
bm.init("", "Base title");
}
public function doEvent(evt:BrowserChangeEvent):void {
eventDG.dataProvider.addItem(evt);
}
]]>
</mx:Script>
<mx:Array id="dp">
<mx:Object label="one"/>
<mx:Object label="two"/>
<mx:Object label="three"/>
</mx:Array>
<mx:ComboBox id="cb"
dataProvider="{dp}"
change="bm.setFragment('selectedItem=' + cb.selectedItem.label);"
/>
<mx:DataGrid id="eventDG"
dataProvider="[]"
width="100%"
variableRowHeight="true"
wordWrap="true"
height="500"
/>
</mx:Application>
ブラウザのアドレスバーの URL フラグメントを変更すると、browserURLChange イベントがトリガされますが、FireFox ではページのリロードはトリガされません。Internet Explorer では、シャープ記号(#)の右側にあるアドレスの一部を変更すると、ページのリロードがトリガされます。
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート