Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 48 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
48
Dung lượng
11,08 MB
Nội dung
ptg 280 LESSON : Creating and Dispatching Events 3 Add an <fx:Metadata> tag to this class. Inside it, declare that ProductItem.mxml will dispatch two events, named addProduct and removeProduct. Indicate that both events will be of type events.ProductEvent. <fx:Metadata> [Event(name=”addProduct”,type=”events.ProductEvent”)] [Event(name=”removeProduct”,type=”events.ProductEvent”)] </fx:Metadata> is DataGroup is going to use the components.ProductItem renderer. As you declared earlier, that itemRenderer will dispatch two bubbling events: addProduct and removeProduct. As you saw in the EventLab, when an event bubbles, you can listen for the event on any of the parent instances. In this case, you will listen for the addProduct and removeProduct events on the ProductList. 4 Save the ProductList class. It should read as follows: <?xml version=”1.0” encoding=”utf-8”?> <s:DataGroup xmlns:fx=”http://ns.adobe.com/mxml/2009” xmlns:s=”library://ns.adobe.com/flex/spark” xmlns:mx=”library://ns.adobe.com/flex/mx” item Re nderer=”com ponents.ProductIte m”> <s:layout> <s:VerticalLayout/> </s:layout> <fx:Declarations> <! Place non-visual elements (e.g., services, value objects) here > </fx:Declarations> <fx:Metadata> [Event(name=”addProduct”,type=”events.ProductEvent”)] [Event(name=”removeProduct”,type=”events.ProductEvent”)] </fx:Metadata> </s:DataGroup> Using the ProductList Component Yo u w i l l n o w r e p l a c e t h e D a t a G r o u p i n y o u r S h o p p i n g Vi e w w i t h y o u r n e w P r o d u c t L i s t component. 1 Open the ShoppingView.mxml le and locate the DataGroup on approximately line 40. 2 Directly below the DataGroup, add a ProductList component. If you used code-completion, Flash Builder automatically added a components name space on your behalf. If you did not, you will need to add this namespace manually. <components:ProductList/> From the Library of Wow! eBook Download from www.eBookTM.com ptg 281 Creating and Using the ProductEvent Class 3 Many of the properties on the DataGroup will be the same on your new ProductList. Copy the width, height, and visible properties (for both the normal and cartView state) to your ProductList tag. <components:ProductList width=”100%” height=”100%” width.cartView=”0” height.cartView=”0” visible.cartView=”false”/> 4 Finally, move the dataProvider property to the new ProductList and delete the DataGroup. Your new ProductList tag should look like the following code: <components:ProductList width=”100%” height=”100%” width.cartView=”0” height.cartView=”0” visible.cartView=”false” dataProvider=”{groceryInventory}”/> 5 Save this le and run the application. You shouldn’t receive any errors, and the Products should display as before. Using ProductEvent to Add and Remove a Product An instance of the ProductEvent class is bubbling up the display list each time the AddToCart button is clicked. You are now going to listen to that event and use it to actually add the prod- uct to the cart. 1 Open ShoppingView.mxml from the views package. 2 Inside the Script block, add a new private method named addProductHandler(). is function will accept a single parameter named event of type ProductEvent and return void. Tip: In this case we are writing the event handlers manually. When Flash Builder automatically creates an event handler on your behalf, it normally names it to correspond to the control that is using the event (so, something like productlist1_addProductHandler() if the ProductList were using it). That is fine in most cases, but this particular handler is going to be used by multiple controls, so we are naming it manually. 3 Still inside the Script block, add another new private method named removeProductHandler(). is function will also accept a single parameter named event of type ProductEvent and return void. private function addProductHandler(event:ProductEvent):void { } private function removeProductHandler(event:ProductEvent):void { } From the Library of Wow! eBook Download from www.eBookTM.com ptg 282 LESSON : Creating and Dispatching Events If you did not use code-completion, add the import for events.ProductEvent at this time. Again, we are making these methods private as they are not needed outside this class. 4 Inside the addProductHandler() method, create a new local variable named sci of type ShoppingCartItem. Set this variable equal to a new instance of the ShoppingCartItem class, passing the product property of your event object to its constructor. var sci:ShoppingCartItem = new ShoppingCartItem( event.product ); Yo u a l r e a d y d i d t h e h a r d w o r k b y e n s u r i n g t h e e v e n t w o u l d h a v e a r e f e r e n c e t o t h e clicked product available. Now you simply need to use it. 5 Still inside the addProductHandler() method, add the ShoppingCartItem instance to the shopping cart using the addItem() method of the shoppingCart reference. Your code should look like this: private function addProductHandler(event:ProductEvent):void { var sci:ShoppingCartItem = new ShoppingCartItem( event.product ); shoppingCart.addItem( sci ); } 6 Duplicate this concept inside the removeProductHandler() method. Create a new local variable named sci of type ShoppingCartItem and assign it a new ShoppingCartItem instance with event.product passed to its constructor. However, in this case, call the removeItem() method of the shoppingCart, passing the local sci variable. private function removeProductHandler(event:ProductEvent):void { var sci:ShoppingCartItem = new ShoppingCartItem( event.product ); shoppingCart.removeItem( sci ); } Yo u n o w h a v e t w o e v e n t h a n d l e r s r e a d y t o a d d o r r e m o v e p r o d u c t s f r o m t h e c a r t . Yo u will now simply indicate that these two handlers should be used by your ProductList for this purpose. 7 Find the ProductList tag and indicate that you will handle the ProductList’s addProduct event with the addProductHandler() method, passing the event object. <components:ProductList x=”0” y=”0” width=”100%” height=”100%” width.cartView=”0” height.cartView=”0” visible.cartView=”false” dataProvider=”{groceryInventory}” addProduct=”addProductHandler(event)”/> 8 Next, indicate that you will handle the ProductList’s removeProduct event with the removeProductHandler() method, passing the event object. From the Library of Wow! eBook Download from www.eBookTM.com ptg 283 Creating and Using the ProductEvent Class <components:ProductList x=”0” y=”0” width=”100%” height=”100%” width.cartView=”0” height.cartView=”0” visible.cartView=”false” dataProvider=”{groceryInventory}” addProduct=”addProductHandler(event)” removeProduct=”removeProductHandler(event)”/> 9 Save this class and run the FlexGrocer application. Yo u s h o u l d n o w b e a b l e t o a d d a n d r e m o v e p r o d u c t s a g a i n u s i n g t h e b u t t o n s , b u t i t i s n o w performed with events across components in a loosely coupled way. Handling the Collection Change Event As you already know, many Flex components and classes, some visual and some non-visual, dispatch events that can be used in your application. In this exercise, you will perform a minor refactoring of the ShoppingCart class and use one of these events to ensure that the total of your ShoppingCart class always remains correct as you add and remove items. 1 Open ShoppingCartView.mxml from the views package. 2 Find the Label tag that displays the text Your Cart Total: $. Yo u w i l l n o w c h a n g e t h i s L a b e l t o r e e c t t h e c a r t ’s a c t u a l t o t a l . 3 Change the Label to append the total property of the ShoppingCart instance, named shoppingCart, directly aer the currency symbol. Surround the expression that retrieves the total in curly brackets, indicating that it should be refreshed if the total changes. Your code should look like this: <s:Label text=”Your Cart Total: ${shoppingCart.total}”/> Flex will concatenate the initial portion of that string and the total property each time a change in the total is noted. However, there is still one bug in our ShoppingCart class that needs to be xed. In Lesson 8, “Using DataBinding and Collections,” we added an implicit getter and set- ter to the ShoppingCartItem. Each time the ShoppingCartItem’s quantity changes, we update the subtotal for that particular item. Unfortunately, the ShoppingCart itself also has a total property. Right now, even though the subtotal for each item adjusts correctly, the ShoppingCart’s overall total is not aware of that change and will therefore not rerun the calculateTotal() method. Eectively, this means that if you update quantities of given items through a method other than add or remove, the ShoppingCart total will not track correctly. From the Library of Wow! eBook Download from www.eBookTM.com ptg 284 LESSON : Creating and Dispatching Events 4 Open the ShoppingCart class from the cart package. 5 As the last item in the class, add a new method named handleItemsChanged(). is method will accept a single parameter named event of type CollectionEvent. If you used code-completion, CollectionEvent will be imported for you. If not, import mx.events.CollectionEvent now. CollectionEvent is a special type of event broadcast from collections such as the ArrayCollection. It indicates that one of the items in the collection has changed. 6 Inside the named handleItemsChanged() method, call the calculateTotal() method of this object. private function handleItemsChanged( event:CollectionEvent ):void { calculateTotal(); } Every time the items in the ShoppingCart change, we will respond by recalculating the total for the cart. In this way we can keep track of the changes to the total correctly. 7 Find the constructor for the ShoppingCart class. As the last line of the constructor, you will add an event listener to the ite ms ArrayCollection for the CollectionEvent. COLLECTION_CHANGE event type. When this event occurs you want the handleItemsChanged method called. items.ad dEventListener(CollectionEvent.COLLECTION_CHANGE, handleItem sChang ed ); If you use code-completion, Flash Builder will write much of this line on your behalf. is is simply the ActionScript equivalent of adding an event listener in MXML and pass- ing the event object. e rst parameter of the addEventListener() call is always a String specifying the type of event. Unfortunately, in ActionScript, unlike in MXML, Flash Builder doesn’t look at the event metadata and ll in String on our behalf. It is therefore a common convention to create constants in the system, which are just strings with the name of the event preset on your behalf. is simply prevents you from making a typo by ensuring that the event type that you want to listen for does in fact exist. Last thing to note: When you add an event listener in ActionScript, the second argument is a function reference. So you don’t type handleItemsChanged( event ) as you would in MXML, but rather just handleItemsChanged. From the Library of Wow! eBook Download from www.eBookTM.com ptg 285 What You Have Learned Tip: If you want to see how the constant works for yourself, hold down the Ctrl key and click COLLECTION_CHANGE. Flash Builder will take you to the CollectionEvent class and you will see a constant. This line of code works the same whether you use the constant or type the string collectionChange. 8 Find the addItem() method and remove the call to calculateTotal(). Any change to the ite ms ArrayCollection will now inform the ShoppingCart to recalcu- late itself. You no longer need to call this explicitly when adding or removing an item. 9 Find the removeItem() method and also remove the call to calculateTotal(). 10 Save this class and run the FlexGrocer application. Yo u c a n n o w a d d a n d r e m o v e i t e m s f r o m t h e c a r t . A s t h e s e i t e m s c h a n g e , t h e t o t a l u p d a t e s automatically as it responds to a notication from the items ArrayCollection. What You Have Learned In this lesson, you have: Learned the benets of loosely coupled architecture (pages 258–259)• Dispatched events (pages 259–263)• Declared events for a component (pages 263–265)• Identied the need for your own event classes (pages 265–266)• Created and used an event subclass (pages 266–270)• Learned about event bubbling (pages 270–275)• Created the ProductEvent class (pages 276–281)• Used ProductEvent to add and remove a product from the cart (pages 281–283)• Used CollectionEvent to update the cart total (pages 283–285)• From the Library of Wow! eBook Download from www.eBookTM.com ptg LESSON 12 What You Will Learn In this lesson, you will: Dene the viewable columns of a DataGrid through DataGridColumn• Use a • labelFunction and an itemRenderer to display DataGridColumn information Create an MXML component to be used as an item renderer• Create an inline custom item renderer for a DataGridColumn• Raise events from inside an item renderer • Sort the AdvancedDataGrid• Style rows, columns, and cells in an AdvancedDataGrid• Group data in an AdvancedDataGrid using both tags and ActionScript to • manipulate the grid’s data provider Display summary data in an AdvancedDataGrid using both tags and • ActionScript Approximate Time is lesson takes approximately 2 hours to complete. From the Library of Wow! eBook Download from www.eBookTM.com ptg 222888777 Lesson 12 Using DataGrids and Item Renderers In Lesson 10, “Using DataGroups and Lists,” you worked with datasets and some controls that can be used to show the data. In this lesson, you will build on that set of base controls and be introduced to the primary MXML component used to display and manipulate large datasets. In this lesson, you will learn how to use the DataGrid component to display a dataset in an interactive way using rows and columns. Aside from using the DataGrid in its simplest form, you will learn how to override the default behavior of a particular column in the DataGrid by implementing a custom item renderer; do a custom sort of the data in a column; and change the editing controls that manage the underlying data. You will also use the sorting, styling, grouping, and summary data features of the AdvancedDataGrid. The shopping cart displayed in a DataGrid From the Library of Wow! eBook Download from www.eBookTM.com ptg 288 LESSON : Using DataGrids and Item Renderers Spark and MX So far in this book we have managed to ignore a fundamental aspect of developing in Flex, which is the use of multiple component sets. Flex 4 is the rst version of Flex to have more than one set of components, meaning that there are really two types of Labels, two types of Buttons, and two types of TextInputs, among other controls. ese two types are referred to as MX and Spark. e MX set of controls has been under constant evolution since Flex 1.0. e same basic con- trols, with the same metaphors, have slowly developed over a number of releases. is set of controls worked primarily through the object-oriented concept of inheritance, meaning that if you wanted a control to behave in a new way, you extended the previous control and changed some portion of its functionality. Spark is a brand-new set of controls making their rst appearance in Flex 4. In the Spark set of controls, components are built through the concept of composition. You have actually been working with this all along. When you wanted a group to be horizontal or vertical, you com- bined the Group with a HorizontalLayout or VerticalLayout. is is composition. While Spark is the future of Flex, it is not all-encompassing yet, meaning that the many years of development that went into developing the MX component produced a component set with huge diversity and functionality. Spark has had much less development time, so while it performs extremely well, it does not have breadth of function that MX has today. erefore in Flex 4, we combine Spark and MX controls to achieve what we desire. Whenever possible, we embrace Spark components, as they are easier to customize, are oen more performant, and will be the focus of continuing improvements. When Spark does not have a feature we need yet (such as the Form, DataGrid, and AdvancedDataGrid), we use the MX versions, which integrate nicely with Spark and allow us to complete our component set. Introducing DataGrids and Item Renderers Using a DataGrid as a way to display the data of your application provides the largest possible number of options for your users to interact with the data. At the simplest level, the DataGrid organizes the data in a column-by-row format and presents this to the user. From there, the DataGrid can be congured to allow you to modify the data it contains. In this lesson, you will make modications to FlexGrocer, in which the DataGrid will give you a view of the cart and the ability to both update and remove items from the cart. From the Library of Wow! eBook Download from www.eBookTM.com ptg 289 Displaying the ShoppingCart with a DataGrid Tip: Although the DataGrid does provide the most versatile manner of interacting with the data of your application, it does come with additional overhead (performance and size). It is wise to consider what you expect the user to do with the data or controls before you automati- cally choose to use a DataGrid. Displaying the ShoppingCart with a DataGrid When you le o in Lesson 11, “Creating and Dispatching Events,” you had the contents of your cart displayed in a List control with the ability to remove the current item you were viewing via a Remove From Cart button. You will now use a DataGrid to display the contents of the cart. e DataGrid control supports the syntax that allows you to specify the columns explicitly through the DataGridColumn: <mx:DataGrid … > <mx:columns> <mx:DataGridColumn dataField=””…> <mx:DataGridColumn…> <mx:DataGridColumn…> </mx:columns> </mx:DataGrid> e dataField is used to map a property in the dataset to a given column. e order in which the DataGridColumns are listed is the order you will see the columns from le to right in the DataGrid. is is useful when you need to specify a dierent order of the columns from the one specied in the dataset. Each DataGridColumn supports a large number of attributes that aect the DataGrid’s rendering and interaction with the given column. 1 Locate the components package that you used in the previous exercise. Alternatively, if you didn’t complete the previous lesson or your code is not function- ing properly, you can import the FlexGrocer.fxp project from the Lesson12/start folder. Please refer to Appendix A for complete instructions on importing a project should you ever skip a lesson or if you ever have a code issue you cannot resolve. 2 Right-click the components package and choose New > MXML Component. In the dia- log box, specify the Name to be CartGrid. 3 For the “Based on” value, click the Browse button. In the dialog box, begin to type DataGrid until you see DataGrid – mx.controls displayed. Choose the DataGrid entry. Click OK, then Finish. From the Library of Wow! eBook Download from www.eBookTM.com [...]... Download from www.eBookTM.com From the Library of Wow! eBook 302 LESSON 12 : Using DataGrids and Item Renderers 7 Save CartGrid.mxml Run the FlexGrocer.mxml application, add the Buffalo product to the shopping cart, and click View Cart Notice both the formatting on the Amount column and the Remove button in the shopping cart Using the AdvancedDataGrid The AdvancedDataGrid expands the capabilities of the. .. removeProduct=”removeProductHandler( event )”/> The extended event is handled in the CartGrid component The removeProductHandler() method you built in the previous lesson does the removal of the product from the cart 7 Run FlexGrocer and add items to the cart Click the View Cart button and confirm you can remove items from the cart using the Remove button Create a labelFunction to Display the Subtotal You need to create... location add the component Set the id to dgCart, the includeIn to cartView, and the width and height to 10 0% 4 In the CartGrid, bind the dataProvider to shoppingCart.items 5 Run the FlexGrocer.mxml Add products to the shopping cart, and then click the View Cart... the import statements made at the top of the file are in a scope different from the inline item renderer Download from www.eBookTM.com From the Library of Wow! eBook 298 LESSON 12 : Using DataGrids and Item Renderers Reusing the ProductEvent Class At this point there is no removeItem() method in your renderer When you create this method you will reuse code created in the previous lesson In Lesson 11 ... editable=”false”/> 11 Save CartGrid.mxml Using the CartGrid Component You’ve created the basic component that uses a DataGrid to display data in the shopping cart data structure Now you will replace the placeholder DataGrid that was inserted earlier with the newly created component 1 Open ShoppingView.mxml from the views package 2 Locate the block near the bottom of the file and remove it 3 In the same... do not do the casting Download from www.eBookTM.com From the Library of Wow! eBook Displaying the ShoppingCart with a DataGrid 295 4 Place an tag for the product name below the tag Bind the text attribute to ( data.product as Product ).prodName Set the height and width to 10 0% 5 Save the ProductName.mxml... in the header area, you set sorting by category to be the first-priority sort, and the 1 that appears confirms this 4 Now click in the multiple-column sort area for the name column to make it the secondary sort You see that the names are now sorted within categories and the number 2 that appears in the name column confirms this is the second-level sort 5 Click in the qty header area This changes the. .. www.eBookTM.com From the Library of Wow! eBook Using the AdvancedDataGrid 3 07 { } else { } } The if-else statement will be used to control which row will be styled 4 For the condition of the if-else statement, check to see if the cost of the data in the current row is 99 if(data[“cost”]==.99) Remember that the data parameter contains all the data of a particular row of the grid So, the if statement is... This will apply the function only to the cost column of the grid Download from www.eBookTM.com From the Library of Wow! eBook Using the AdvancedDataGrid 309 4 Run the application and note only the cells containing 99 are styled 5 Close the StyleCellADG.mxml file Grouping Data Grouping data is an often-requested feature of the DataGrid and is now implemented in the AdvancedDataGrid The grouping feature... height=”200”> The refresh() method of the GroupingCollection2 class actually applies the grouping to the data 7 Run the application again, and you will see the data grouped on the category field 8 Close the GroupWithTagsADG.mxml file Grouping data with ActionScript Rather than add tags to the AdvancedDataGrid as you did in the last task, this exercise will now manipulate the dataProvider using ActionScript The . built in the previous lesson does the removal of the product from the cart. 7 Run FlexGrocer and add items to the cart. Click the View Cart button and conrm you can remove items from the cart. the vertical layout to help center the button in the DataGrid no matter the size of the cell. 5 Place an <s:Button> tag aer the layout but before the end of the MXItemRenderer. Set the. bottom of the le and remove it. 3 In the same location add the <components:CartGrid> component. Set the id to dgCart, the includeIn to cartView, and the width and height to 10 0%. 4 In the CartGrid,