一般的な使用例としては、ユーザーがフォームの入力を開始してから、後で使用するためにフォームをブックマークに登録したり、入力した値を見てもらうために他人に URL を送信したりすることが挙げられます。多くの場合、フォームは Tab Navigator および Accordion コンテナなどのナビゲータコンテナとして実装されます。
これがディープリンクの問題となる場合があります。それは、ビューでまだ表示されていない(したがって、まだインスタンス化されていない)コントロールのプロパティを読み取ろうとすることがあるためです。解決方法の 1 つは、遅延インスタンス化を無効にし、コンテナの creationPolicy プロパティの値を all に設定することです。これにより、コントロールが最初に表示されるかどうかにかかわらず、アプリケーションの起動時にすべてのビューのすべてのコントロールをインスタンス化するように Flex に指示します。これは、アプリケーションの起動時に余分なオーバーヘッドが発生し、プロセッサ時間とメモリを不必要に使用することになる可能性があるため、お勧めしません。creationPolicy プロパティの値を all に設定すると、ユーザーインターフェイスの複雑さによっては、Flex アプリケーションのパフォーマンスが著しく低下し、優れたユーザー操作性が損なわれることがあります。作成ポリシーについて詳しくは、creationPolicy プロパティについてを参照してください。
遅延インスタンス化を使用しない方法では、状態を保持するプロパティの値を URL の値にバインドします。まだ作成されていないコントロールは、作成時にそれらの値を適用します。この方法には、ビューのコントロールを最初に作成することなく、URL とアプリケーションの状態を同期させて相互に保持するという利点があります。
そのためには、起動時に URL の値に割り当てられる変数を設定し、ユーザーの操作に応じてそれらの値をアプリケーションと同期させて保持します。アプリケーションの起動時に、バインドされたプロパティの値を、URL から取得した値に設定します(URL に値がある場合)。次に、アプリケーションの状態が変更されたとき(ユーザーが新しいパネルに移動したときやチェックボックスをクリックしたときなど)は常に、バインドされたプロパティを新しい値に更新します。URL のプロパティのフラグメントの値も更新します。
しかし、これを行うと、まだインスタンス化されていないコンポーネントのプロパティに変数の値を設定しようとすることになるため、変数を割り当てるコードを try/catch ブロックで囲む必要があります。これにより、割り当てエラーはランタイムエラーとしてスローされるのではなく、キャッチされます。
次の例では、Tab Navigator コンテナを使用して、ユーザーが支払い処理を完了できるようにしています。ユーザーがパネルを変更したり、TextInput コントロールの値を変更したり、CheckBox コントロールのチェックをオンにしたりすると、URL およびバインドされたプロパティは常に更新されます。いつでも、URL のブックマークを作成し、ブラウザを閉じて、後でアプリケーションに戻ることができます。すべてのプロパティの値は、ブックマークに登録された URL に保持されます。
<?xml version="1.0" encoding="utf-8"?>
<!-- deeplinking/ComplexMultiPanelExample.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
historyManagementEnabled="false"
creationComplete="init();parseURL(event)"
>
<mx:Script>
<![CDATA[
import mx.events.BrowserChangeEvent;
import mx.managers.IBrowserManager;
import mx.managers.BrowserManager;
import mx.utils.URLUtil;
private var bm:IBrowserManager;
[Bindable]
private var agreeBoxFromURL:Boolean;
[Bindable]
private var personNameFromURL:String;
[Bindable]
private var hometownFromURL:String;
[Bindable]
private var cctypeFromURL:int;
[Bindable]
private var ccnumberFromURL:String;
private function init():void {
bm = BrowserManager.getInstance();
bm.addEventListener(BrowserChangeEvent.BROWSER_URL_CHANGE, parseURL);
bm.init("", "Welcome!");
}
/* This method is called once when application starts up. It is also
called when the browser's address bar changes, either due to user action
or user navigation with the browser's Forward and Back buttons. */
private function parseURL(event:Event):void {
var o:Object = URLUtil.stringToObject(bm.fragment, "&");
if (o.panel == undefined)
o.panel = 0;
tn.selectedIndex = o.panel;
tn.validateNow();
personNameFromURL = o.personName;
hometownFromURL = o.hometown;
ccnumberFromURL = o.ccnumber;
cctypeFromURL = o.cctype;
agreeBoxFromURL = o.agreeBox;
}
public function updateTitle(e:Event):void {
l1.text += "updateTitle()\n";
bm.setTitle("Welcome " + personName.text + " from " + hometown.text + "!");
}
private function updateURL():void {
/* Called when state changes in the application, such as when the panel changes,
or a checkbox is checked.
You must wrap the following assignments in a try/catch block, otherwise the
application tries to access components that have not yet been created.
You can circumvent this by setting the container's creationPolicy to "all",
but that is not a good solution for performance reasons. */
try {
personNameFromURL = personName.text;
hometownFromURL = hometown.text;
ccnumberFromURL = ccnumber.text;
cctypeFromURL = cctype.selectedIndex;
agreeBoxFromURL = agreeBox.selected;
} catch (e:Error) {
}
var o:Object = {};
try {
o.panel = tn.selectedIndex;
o.personName = personName.text;
o.hometown = hometown.text;
o.ccnumber = ccnumber.text;
o.cctype = cctype.selectedIndex;
o.agreeBox = agreeBox.selected;
} catch (e:Error) {
} finally {
var s:String = URLUtil.objectToString(o, "&");
bm.setFragment(s);
}
}
]]>
</mx:Script>
<mx:TabNavigator id="tn" width="300" change="updateURL()">
<mx:Panel label="Personal Data">
<mx:Form>
<mx:FormItem label="Name:">
<mx:TextInput id="personName"
text="{personNameFromURL}"
focusOut="updateURL()"
enter="updateURL()"
/>
</mx:FormItem>
<mx:FormItem label="Hometown:">
<mx:TextInput id="hometown"
text="{hometownFromURL}"
focusOut="updateURL()"
enter="updateURL()"
/>
</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 id="cctype"
change="updateURL()"
selectedIndex="{cctypeFromURL}"
>
<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"
text="{ccnumberFromURL}"
focusOut="updateURL()"
enter="updateURL()"
/>
</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 id="agreeBox"
label="Agree"
selected="{agreeBoxFromURL}"
click="updateURL()"
/>
</mx:Panel>
</mx:TabNavigator>
<mx:TextArea id="l1" height="400" width="300"/>
</mx:Application>
updateURL() メソッドを使用してバインド可能な変数の値を更新する方法以外にも、イベントハンドラを使用してその値を設定する方法もあります。例えば、居住地の TextInput コントロールの値を変更する場合、focusOut および enter イベントハンドラを使用して hometownFromURL プロパティの値を設定できます。
<mx:TextInput id="hometown"
text="{hometownFromURL}"
focusOut="hometownFromURL=hometown.text;updateURL()"
enter="hometownFromURL=hometown.text;updateURL()"
/>
この例では、コントロールのプロパティが変更されると、ビューのコントロールによりモデルが更新されます。これは、モデルとビューのよりクリーンな分離を強制するのに役立ちます。
このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート