(十四)Flex 4_ツールバーの

20923 ワード

Flexでナビゲーションを実現するには2つの方法があります
1.ステータスを使用して、異なるイベントが発生したときに指定されたステータスに切り替え、異なるステータスが異なるビューインタフェースに対応する
2.ナビゲーションコンテナの使用
--------------------------------------------------------------------
ナビゲーション:マルチページビューの切り替え表示を実現する
1.ナビゲーション基盤を実現するViewStackクラス
2.ViewStackでSparkベースのコンテナの使用をサポートするNavigationContentクラス
3.ナビゲーションの実装時にViewStackクラスのselectedIndexとselectedChild属性を使用する
ナビゲーションコンテナ
重要な概念:
    コンテナ:ViewStack
    コンポーネント:NavigationContent  (Spark要素)
説明:
INavigationContentインタフェースを実装したクラスは、ViewStackのサブ要素として使用できます.
SparkではNavigationContentがINavigationContentを実現しSprak Groupクラスを継承する
ナビゲーションコンテナにはサブエレメントが1つずつ表示され、ViewStackはサブエレメントの可視性を切り替えることでサブエレメントの表示を実現します.
要素をどのように切り替えますか?
    selectedChildとselectedIndex属性によって要素のナビゲーションコンテナでの可視性を制御する
[selectedIndex:ViewStackインデックス0から、最初のサブエレメントのインデックス0]
[selectedChilde:子要素のid値を参照することにより、ViewStackがどの要素を表示するかを指定する]
----------------------------------------------------------------
1.メインプログラムの設定状態:
	<s:states>
		<s:State name="shoppingView"/>
		<s:State name="checkoutView"/>
	</s:states>

1つはショッピング状態(対応ショッピングコンポーネント)、1つは決済状態(対応決済コンポーネント)であり、異なる状態で異なるインタフェースに切り替わる.
カートインスタンスは、メインプログラムで作成され、コンポーネントのプロパティによってバインドされ、ショッピングと決済時のカートの共有が実現されます.
インタフェースには様々なボタンがあり、クリックするとclickイベントが発生し、対応するイベント処理関数にcurrentStateを設定すると状態の切り替えが可能になります!
ユーザーが商品を選択して決済すると、カスタムイベントplaceOrderが発生し、メインプログラムで傍受して処理する:ダイアログボックスをポップアップし、ショッピングの簡単な情報を表示し、最後にショッピングカートを空にし、プログラムの各状態を初期状態に戻す!
FlexGrocer.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   creationComplete="handleCreationComplete(event)" xmlns:views="views.*" xmlns:services="services.*" xmlns:cart="cart.*">
	
	<!--     、    -->
	<s:states>
		<s:State name="shoppingView"/>
		<s:State name="checkoutView"/>
	</s:states>
	
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
		<!--  HTTPService           ActionScript      ,       -->
		<!--            (     )-->
		<services:CategoryService id="categoryService"/>
		<!--              (     )-->
		<services:ProductService id="productService"/>
		
		<!--        ,         shoppingView checkoutView     -->
		<cart:ShoppingCart id="shoppingCart"/>
	</fx:Declarations>

	<fx:Script>
		<![CDATA[
			import events.OrderEvent;
			
			import mx.controls.Alert;
			import mx.events.FlexEvent;
			
			import spark.events.IndexChangeEvent;
			//          ,       ,          ,    
			//        ,                 
			private function handleCreationComplete(event:FlexEvent):void {
				categoryService.send();
				productService.send();
			}
			
			//           
			private function handleViewCartClick( event:MouseEvent ):void {
				bodyGroup.currentState="cartView";//   bodyGroup  cartView  
			}
			
			//       , change      
			protected function list1_changeHandler(event:IndexChangeEvent):void
			{
				//               ,   change  ,         
				//         catID,  products      id      ,          
				productService.filterCollection(event.target.selectedItem.categoryID);
			}
			
			protected function btnCheckout_clickHandler(event:MouseEvent):void
			{
				//       
				this.currentState = "checkoutView";
			}
			
			protected function FlexGrocer_clickHandler(event:MouseEvent):void
			{
				//       
				this.currentState = "shoppingView";
			}
			
			//       checkoutView    placeOrder       ,        
			protected function checkout_placeOrderHandler(event:OrderEvent):void
			{
				//      ,           
				Alert.show("Place an order for " +event.order.billingName + 
					" with a total of " + shoppingCart.total,"Order Placed");
				//     
				shoppingCart = new ShoppingCart();
				
				//             
				this.currentState = "shoppingView";
				
				//  ShoppingView    cartView  ,     State1  
				bodyGroup.currentState = "State1";
			}
			
		]]>
	</fx:Script>
	
	<!--       -->
	<s:controlBarLayout>
		<s:BasicLayout/>
	</s:controlBarLayout>
	
	<!--     -->
	<s:controlBarContent>
		<s:Button y="10" label="Checkout" id="btnCheckout" right="10"
				  click="btnCheckout_clickHandler(event)"/>
		<s:Button y="10" label="View Cart" id="btnCartView" right="90" 
				  click="handleViewCartClick( event )"/>
		<s:Button label="Flex Grocer" x="5" y="5"
				  click="FlexGrocer_clickHandler(event)"/>
		
		<!--  categoryService          ,          NavigationItem    -->
		<s:List left="200" height="52" 
				dataProvider="{categoryService.categories}"
				itemRenderer="components.NavigationItem"
				change="list1_changeHandler(event)"
				includeIn="shoppingView">
			<s:layout>
				<s:HorizontalLayout/>
			</s:layout>
		</s:List>
	</s:controlBarContent>
	
	<!--        (          ,          ) -->
	<!--  productService      -->
	<views:ShoppingView id="bodyGroup" width="100%" height="100%" 
						groceryInventory="{productService.products}"
						includeIn="shoppingView"
						shoppingCart="{shoppingCart}"/>	
	
	<!--     -->
	<views:CheckOutView x="0" y="0" width="100%" height="100%"
						includeIn="checkoutView"
						shoppingCart="{shoppingCart}"
						placeOrder="checkout_placeOrderHandler(event)"/>
	
	<!--      -->
	<s:Label text="(c) 2009, FlexGrocer" right="10" bottom="10"/>
</s:Application>

CheckOutView.mxml
このコンポーネントは、ユーザーがcheckoutをクリックすると表示されます.
1つのViewStackと3つのNavigationContentを定義し、selectIndexを制御することでナビゲーションを実現
1つ目のナビゲーションページはユーザ基本情報の入力
2つ目のナビゲーションページは銀行カード情報の入力です
3つ目のナビゲーションは決済ページで、左側にはユーザーが前に入力した情報が表示され、右側にはカート内のショッピングの詳細が表示され、ユーザーは決済を選択したり、情報を再編集したりすることができます.
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark" 
		 xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:valueObjects="valueObjects.*" xmlns:checkout="views.views.checkout.*">
	
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	
	<fx:Declarations>
		<!--       (    、   )     -->
		<!--   OrderInfo      -->
		<valueObjects:OrderInfo id="orderInfo"/>
	</fx:Declarations>
	
	<!--      OrderEvent  ( completeOrder         )-->
	<fx:Metadata>
		[Event(name="placeOrder", type="events.OrderEvent")]
	</fx:Metadata>
	
	<fx:Script>
		<![CDATA[
			import cart.ShoppingCart;
			
			import events.OrderEvent;
			
			[Bindable]
			public var shoppingCart:ShoppingCart;
			
			//        
			protected function proceedHandler(event:Event):void
			{
				vs.selectedIndex += 1;
				
			}
			//      ,       
			protected function editInformationHandler(event:Event):void
			{
				vs.selectedIndex = 0;
			}
			//    ,  
			protected function completeOrderHandler(event:Event):void
			{
				//           
				vs.selectedIndex = 0;
				
				//            orderInfo     
				this.dispatchEvent(new OrderEvent('placeOrder',orderInfo));
				
				//       ,       
				orderInfo = new OrderInfo();
			}
			
		]]>
	</fx:Script>
	
	
	<!--   ViewStack  NavigationContent    -->
	<mx:ViewStack id="vs" width="100%" height="100%">
		<!-- page 1        -->
		<checkout:CustomerInfo orderInfo="{orderInfo}" 
							   width="100%" height="100%"
							   proceed="proceedHandler(event)"/>
		<!-- page 2        -->
		<checkout:CreditCardInfo orderInfo="{orderInfo}" 
								 width="100%" height="100%"
								 proceed="proceedHandler(event)"/>
		<!-- page 3              ,         -->
		<checkout:Review orderInfo="{orderInfo}" 
						 width="100%" height="100%"
						 shoppingCart="{shoppingCart}"
						 editInformation="editInformationHandler(event)"
						 completeOrder="completeOrderHandler(event)"/>
	</mx:ViewStack>
</s:Group>

ユーザーがComplete Orderボタンをクリックするとトリガーされるオーダーイベントをカスタマイズ
package events {
	import flash.events.Event;
	
	import valueObjects.OrderInfo;
	
	public class OrderEvent extends Event {
		public var order:OrderInfo;
		
		//                
		//            ,        event        ,            
		public function OrderEvent(type:String, order:OrderInfo ) {
			this.order = order;
			super(type);
		}
		
		override public function clone():Event {
			return new OrderEvent( type, order );
		}
	}
}

以下は3つのナビゲーションページです
最初のユーザ基本情報の入力
ユーザーがproceedをクリックすると、proceedがclickイベントをトリガーし、イベント処理関数にproceedカスタムイベントを配布し、親コンテナでイベントをキャプチャし、イベント処理関数にViewStackのselectedIndexを1加算して2ページ目に移動
<?xml version="1.0" encoding="utf-8"?>
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009" 
					xmlns:s="library://ns.adobe.com/flex/spark" 
					xmlns:mx="library://ns.adobe.com/flex/mx">
	<s:layout>
		<s:HorizontalLayout/>
	</s:layout>
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>

	<fx:Metadata>
		[Event(name="proceed", type="flash.events.Event")]
	</fx:Metadata>
	
	<fx:Script>
		<![CDATA[
			import valueObjects.OrderInfo;
			[Bindable]
			public var orderInfo:OrderInfo;
			
			private function handleProceed( event:Event ):void {
				dispatchEvent( new Event( 'proceed' ) );
			}
		]]>
	</fx:Script>
	<s:Label text="Checkout Page 1 of 3"/>
	<mx:Form>
		<mx:FormHeading label="Customer Information"/>
		<mx:FormItem label="Customer Name">
			<!-- "@"                    ,          ? -->
			<s:TextInput text="@{orderInfo.billingName}"/>
		</mx:FormItem>
		<mx:FormItem label="Address">
			<s:TextInput text="@{orderInfo.billingAddress}"/>
		</mx:FormItem>
		<mx:FormItem label="City">
			<s:TextInput text="@{orderInfo.billingCity}"/>
		</mx:FormItem>
		<mx:FormItem label="State">
			<s:TextInput text="@{orderInfo.billingState}"/>
		</mx:FormItem>
		<mx:FormItem label="Zip">
			<s:TextInput text="@{orderInfo.billingZip}"/>
		</mx:FormItem>
		<mx:FormItem label="Delivery Date">
			<mx:DateField selectedDate="@{orderInfo.deliveryDate}"/>
		</mx:FormItem>
		<mx:FormItem>
			<s:Button label="Proceed" click="handleProceed( event )"/>
		</mx:FormItem>
	</mx:Form>
</s:NavigatorContent>

2番目のユーザーの銀行カード情報の入力、ユーザーはproceedをクリックしてclickイベントが発生して、イベント処理関数の中でproceedカスタムイベントを配布して、親の容器の中でこのイベントに対して捕獲して、イベント処理関数はViewStackのselectedIndexを1プラスして、第3ページにナビゲートします
<?xml version="1.0" encoding="utf-8"?>
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009" 
					xmlns:s="library://ns.adobe.com/flex/spark" 
					xmlns:mx="library://ns.adobe.com/flex/mx">
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>

	<fx:Metadata>
		[Event(name="proceed", type="flash.events.Event")]
	</fx:Metadata>

	<fx:Script>
		<![CDATA[
			import mx.collections.IList;
			
			import spark.events.IndexChangeEvent;
			
			import valueObjects.OrderInfo;
			[Bindable]
			public var orderInfo:OrderInfo;
			
			private function handleProceed( event:Event ):void {
				dispatchEvent( new Event( 'proceed' ) );
			}
		]]>
	</fx:Script>
	<s:Label text="Checkout Page 2 of 3"/>
 
	<mx:Form>
		<mx:FormHeading label="Billing Information"/>
		<mx:FormItem label="Credit Card Type">
			<s:DropDownList selectedItem="@{orderInfo.cardType}" requireSelection="true">
				<s:dataProvider>
					<s:ArrayList>
						<fx:String>American Express</fx:String>
						<fx:String>Diners Club</fx:String>
						<fx:String>Discover</fx:String>
						<fx:String>MasterCard</fx:String>
						<fx:String>Visa</fx:String>
					</s:ArrayList>
				</s:dataProvider>
			</s:DropDownList>
		</mx:FormItem>
		<mx:FormItem label="Card Number">
			<s:TextInput text="@{orderInfo.cardNumber}"/>
		</mx:FormItem>
		<mx:FormItem label="Expiration" direction="horizontal">
			<s:DropDownList selectedItem="@{orderInfo.cardExpirationMonth}" requireSelection="true">
				<s:dataProvider>
					<s:ArrayList>
						<fx:String>January</fx:String>
						<fx:String>February</fx:String>
						<fx:String>March</fx:String>
						<fx:String>April</fx:String>
						<fx:String>May</fx:String>
						<fx:String>June</fx:String>
						<fx:String>July</fx:String>
						<fx:String>August</fx:String>
						<fx:String>September</fx:String>
						<fx:String>October</fx:String>
						<fx:String>November</fx:String>
						<fx:String>December</fx:String>
					</s:ArrayList>
				</s:dataProvider>
			</s:DropDownList>
			<s:DropDownList selectedItem="@{orderInfo.cardExpirationYear}" requireSelection="true">
				<s:dataProvider>
					<s:ArrayList>
						<fx:String>2010</fx:String>
						<fx:String>2011</fx:String>
						<fx:String>2012</fx:String>
						<fx:String>2013</fx:String>
						<fx:String>2014</fx:String>
						<fx:String>2015</fx:String>
					</s:ArrayList>
				</s:dataProvider>
			</s:DropDownList>
		</mx:FormItem>
		<mx:FormItem>
			<s:Button label="Proceed" click="handleProceed( event )"/>
		</mx:FormItem>
	</mx:Form>
	
</s:NavigatorContent>

3番目の決済ページでは、ユーザーがEdit Informationボタンをクリックしてclickイベントをトリガーし、イベント処理関数にカスタムイベントを配布します.editInformationイベント、親コンテナがイベントを傍受し、イベント処理関数でViewStackのselectedIndexを0に設定します.
ユーザはComplete Orderボタンをクリックしてclickイベントをトリガーし、イベント処理関数にカスタムイベント:completeOrderイベントを配布し、親コンテナ(CheckOutView.mxml)がこのイベントを傍受し、イベント処理関数の中で:ポップアップダイアログボックスで、ショッピングに関する簡単な情報を提示し、その後、カートを空にし、プログラムの初期状態などを回復する.
<?xml version="1.0" encoding="utf-8"?>
<s:NavigatorContent xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark" 
		 xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:components="components.*">
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>

	<fx:Metadata>
		[Event(name="editInformation", type="flash.events.Event")]
		[Event(name="completeOrder", type="flash.events.Event")]
	</fx:Metadata>

	<fx:Script>
		<![CDATA[
			import cart.ShoppingCart;
			import cart.ShoppingCartItem;
			
			import events.OrderEvent;
			import events.ProductEvent;
			
			import valueObjects.OrderInfo;
			import valueObjects.Product;

			[Bindable]
			public var shoppingCart:ShoppingCart;
			
			[Bindable]
			public var orderInfo:OrderInfo;
			
			private function handleComplete( event:Event ):void {
				dispatchEvent( new Event( 'completeOrder' ) );  
			}
			
			private function handleEdit( event:Event ):void {
				dispatchEvent( new Event( 'editInformation' ) );	
			}

			private function removeProductHandler(event:ProductEvent):void {
				var sci:ShoppingCartItem = new ShoppingCartItem( event.product );
				shoppingCart.removeItem( sci );
			}			

		]]>
	</fx:Script>
	<s:Label text="Checkout Page 3 of 3"/>
	
	<s:HGroup width="100%" height="90%">
		<!--                 -->
		<mx:Form>
			<mx:FormHeading label="Review and Checkout"/>
			<mx:FormItem label="Name">
				<s:Label text="{orderInfo.billingName}"/>
			</mx:FormItem>
			<mx:FormItem label="Address">
				<s:Label text="{orderInfo.billingAddress}"/>
				<s:Label text="{orderInfo.billingCity}, {orderInfo.billingState} {orderInfo.billingZip}"/>
			</mx:FormItem>
			<mx:FormItem label="Card Type">
				<s:Label text="{orderInfo.cardType}"/>
			</mx:FormItem>
			<mx:FormItem label="Delivery Date">
				<s:Label text="{orderInfo.deliveryDate}"/>
			</mx:FormItem>
			<mx:FormItem>
				<s:Button label="Complete Order" click="handleComplete( event )"/>
				<s:Button label="Edit Information" click="handleEdit( event )"/>
			</mx:FormItem>
		</mx:Form>
		
		<!--             -->
		<s:VGroup width="100%" height="100%">
			<components:CartGrid id="dgCart" 
								 width="100%" height="100%" 
								 dataProvider="{shoppingCart.items}"
								 removeProduct="removeProductHandler( event )"/>
			
			<s:Label text="Total {shoppingCart.total}"/>		
		</s:VGroup>
	</s:HGroup>
</s:NavigatorContent>