3 August 2009
All
Welcome to Part 2 of this tutorial series. In this part, you use ActionScript to create an ArrayCollection instance and populate it with the data needed for the wagon assembly line. You use bindings to tie the ArrayCollection data to the Flex framework DataGrid control; when the data changes in the control it is immediately reflected in the associated colored bins. In Parts 7 and 8 you will replace this dummy data with data from the Web Dynpro application.
Note: Parts 1 through 6 focus on teaching Flex development to SAP developers. Part 7 teaches Flex developers how to create a Web Dynpro application. Parts 8 and 9 show both SAP and Flex developers how to integrate the Flex application as a Rich Island into the Web Dynpro application.
This tutorial introduces the following new variables:
_wagonInventory: The inventory data that populates the colored bins._wagonYellowWarningAmount: The minimum number of wagons that can be created, based on the available inventory, when a bin turns yellow._inventoryNeededForYellow: The number of parts needed in a bin to make the wagons for the _wagonYellowWarningAmount._wagonRedWarningAmount: The minimum number of wagons that can be created, based on available inventory, when you want the bin to turn red and the assembly line to stop._inventoryNeededForRed: The number of parts needed in the bin to make the wagons for the _wagonRedWarningAmount.In Part 2, you created the wagon assembly line layout using MXML tags and CSS selectors. In this section, you use ActionScript to program the business logic for the application. First, you will create an ArrayCollection and populate it with data.
You will place all of your ActionScript code into an MXML Script block.
<mx:Script>
<![CDATA[
]]>
</mx:Script>
The CDATA statement instructs the parser to not process the code as MXML.
CDATA code, use the import statement to import the ArrayCollection class from the mx.collections package.The ArrayCollection class is a wrapper class for arrays that has additional functions to manipulate the array.
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
]]>
</mx:Script>
import statement, declare a private variable named _wagonInventory and data type it to the ArrayCollection class.Note: It is customary to name private variables starting with an underscore. A private variable can only be accessed from within the class in which it is defined.
import mx.collections.ArrayCollection;
private var _wagonInventory:ArrayCollection;
populateData(), that takes no arguments and has a return type of void.Note: A function is reusable code that only executes when triggered or called. The void return type means nothing is returned or sent back from the function to the calling code.
_wagonInventory as an ArrayCollection instance.Note: To instantiate means to create a new object, or instance, of the declared class.
_wagonInventory = new ArrayCollection();
addItem() method of the ArrayCollection class, add the following objects to the _wagonInventory variable:private function populateData():void
{
_wagonInventory= new ArrayCollection();
_wagonInventory.addItem({Title:'TUBS', Quantity:120, Parts:1});
_wagonInventory.addItem({Title:'AXELS', Quantity:190, Parts:2});
_wagonInventory.addItem({Title:'WHEELS', Quantity:320,Parts:4});
_wagonInventory.addItem({Title:'HANDLES', Quantity:61,Parts:1});
_wagonInventory.addItem({Title:'BOXES', Quantity:400, Parts:1});
}
The Title key represents the name of the inventory bin and the Quantity key represents the amount of inventory in the bin. The Parts key represent the number of parts needed for each wagon; in other words, you need four wheels to create one wagon.
The curly braces in this context denote that the Title, Quantity, and Parts values comprise each object in an array. Remember that an ArrayCollection is a wrapper class for arrays.
You should not see any visual changes from Part 2.
In this section, you populate the DataGrid control on initialization of the application.
initialize event that declares the event handler as the populateData() function.The initialize event is dispatched when a component and all of its children have been created, but before the component size has been determined. You will populate the data for the application during this phase of the component life cycle.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
backgroundGradientColors="[0xFFFFFF, 0xFFFFFF]"
initialize="populateData()">
_wagonInventory private variable and make the variable bindable by using the [Bindable] metadata tag.Note: When you make a variable bindable, Flex generates a propertyChange event for the variable that will track when it has changed and will automatically update its value every where it is used.
[Bindable]
private var _wagonInventory:ArrayCollection;
dataProvider property with a value of _wagonInventory using the curly brace syntax that designates a binding.<mx:DataGrid dataProvider="{_wagonInventory}"/>
The dataProvider property for a DataGrid control declares the Array, ArrayCollection, or XML data to display.
Your application should appear as shown in Figure 2.
In this section, you will populate the title and value in the bins.
binTitle0 Label control and delete the text property value.getItemAt()method of the ArrayCollection class and the binding curly braces to retrieve the 0 index Title value of the _wagonInventory data and assign it to the text property.<mx:Label id="binTitle0"
text="{_wagonInventory.getItemAt(0).Title}"
textAlign="center"
width="100"
styleName="titleFont"/>
binTitle1 Label control, delete the text property value and apply the same binding value using index 1.binTitle2 Label control, delete the text property value and apply the same binding value using index 2.binTitle3 Label control, delete the text property value and apply the same binding value using index 3.binTitle4 Label control, delete the text property value and apply the same binding value using index 4.Your application should appear as shown in Figure 3.
binData0 TextInput control and delete the text property value.getItemAt() method to retrieve the 0 index Quantity value of _wagonInventory and assign it to the text property.<mx:TextInput id="binData0" text="{_wagonInventory.getItemAt(0).Quantity}".../>
binData1 TextInput control, delete the text property value and apply the same binding value using index 1.binData2 TextInput control, delete the text property value and apply the same binding value using index 2.binData3 TextInput control, delete the text property value and apply the same binding value using index 3.binData4 TextInput control, delete the text property value and apply the same binding value using index 4.Your application should appear as shown in Figure 4.
<mx:DataGrid dataProvider="{_wagonInventory}"
editable="true"/>
Figure 6 shows the change reflected in the bin.
In this section, you add a listener to the _wagonInventory ArrayCollection instance to change the bin color if the quantity is within a certain threshold range. The bin colors will be green, yellow, or red depending on the quantity value in the bin.
In this section, you will add a listener to _wagonInventory ArrayCollection to do additional processing when the data changes.
import statement in the Script block, import the CollectionEvent class from the mx.events package.import mx.events.CollectionEvent;
populateData() function, create another private function named startProduction() that takes no arguments and has a return type of void.populateData() function.addEventListener() method of the ArrayCollection class to listen for changes in the _wagonInventory data. Listen for the CollectionEvent.COLLECTION_CHANGE event and handle it with the binColorHandler function.Note: You will create the binColorHandler() function later in this tutorial. Do not use the parentheses for the function in the second argument of the addEventListener() method. This is a reference to the function, not a call. Every time the data on the _wagonInventory collection changes, the listener will call the binColorHandler() function.
private function startProduction():void
{
populateData();
_wagonInventory.addEventListener(CollectionEvent.COLLECTION_CHANGE, binColorHandler);
}
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
backgroundGradientColors="[0xFFFFFF, 0xFFFFFF]"
initialize="startProduction()">
In this section, you will create new variables for the calculation of inventory.
_wagonInventory variable, create a private variable named _wagonYellowWarningAmount and data type it to the uint class with a value of 50. This variable will be used to turn the bins yellow when they only have enough inventory to create 50 or fewer wagons.private var _wagonYellowWarningAmount:uint = 50;
_wagonRedWarningAmount and data type it to the uint class with a value of 0 (zero).This variable will be used to turn a bin red, and stop the assembly line, when the bin does not have enough inventory to create any wagons.
_inventoryNeededForYellow and data type it to the uint class.This variable represents the number of parts needed in a bin to make the wagons for the _wagonYellowWarningAmount.
_inventoryNeededForRed and data type it to the uint class. This variable represents the number of parts needed in the bin to make the wagons for the _wagonRedWarningAmount.private var _wagonYellowWarningAmount:uint = 50;
private var _wagonRedWarningAmount:uint = 0;
private var _inventoryNeededForYellow:uint;
private var _inventoryNeededForRed:uint;
In this section, you create the event handler that is called when the ArrayCollection data changes. This function will determine the color for each bin based on the current inventory in the bin and the threshold values.
startProduction() function, create a private function named binColorHandler() which takes one argument named event that is data typed to the CollectionEvent class. Set the argument's default value to null and the function's return type is void.Note: By setting a default value for the event argument, the function will still work when the value is not present.
private function binColorHandler(event:CollectionEvent = null):void
{
}
for loop to loop over the _wagonInventory ArrayCollection instance.for statement, create an iterant named x of type int with a value of 0 (zero).x is less than _wagonInventory.length, iterate the loop using the x++ syntax.private function binColorHandler(event:CollectionEvent =
null):void
{
for (var x:int=0; x < _wagonInventory.length; x++)
{
}
}
Within the for loop, assign the result of _wagonYellowWarningAmount multiplied by the _wagonInventory Parts value to _inventoryNeededForYellow. Use the getItemAt() function and pass x to retrieve the value from the ArrayCollection.
Note: In order to create 50 wagons to reach the yellow threshold, you will need a certain number of wagon parts per bin. For example, to create 50 wagons, you will need 4 wheel parts per wagon for a total of 200 wheels necessary. You will need 2 axels per wagon for a total of 100 axels for 50 wagons.
for (var x:int=0; x < _wagonInventory.length; x++)
{
_inventoryNeededForYellow =
_wagonYellowWarningAmount *
_wagonInventory.getItemAt(x).Parts;
}
_wagonRedWarningAmount multiplied by the _wagonInventory Parts value to _inventoryNeededForRed. Use the getItemAt() function and pass x to retrieve the value from the ArrayCollection.
Note: Currently the _wagonRedWarningAmount is set to zero, which means you will need a minimum of zero parts to display a red bin. However, you will still create this calculation in case you later want to change the threshold value to another amount.
for (var x:int=0; x < _wagonInventory.length; x++)
{
_inventoryNeededForYellow = _wagonYellowWarningAmount * _wagonInventory.getItemAt(x).Parts;
_inventoryNeededForRed = _wagonRedWarningAmount * _wagonInventory.getItemAt(x).Parts;
}
for statement, create a two-part conditional statement, testing first to see if the quantity in _wagonInventory is less than or equal to _inventoryNeededForRed or (double pipe ||) the _wagonInventory quantity is less than the _wagonInventory parts.
Note: If the bin quantity on hand is less than or equal to the total inventory needed for the red threshold or if the bin quantity on hand is less than the parts needed for a wagon, the conditional statement is true. This means you do not have enough inventory left in this bin to create a wagon. This means the bin must change to red.
if ((_wagonInventory.getItemAt(x).Quantity <= _inventoryNeededForRed) ||
(_wagonInventory.getItemAt(x).Quantity < _wagonInventory.getItemAt(x).Parts))
{
}
setStyle() function to set the backgroundColor to red (0xCC0000) for the current binCanvas container. Use this["binCanvas "+ x] for the dynamic instance.
Note: The setStyle() function is used to change the style for a display element at runtime. The this keyword refers to the current scope and the ["binCanvas" + x] syntax builds the instance reference dynamically (binCanvas0, binCanvas1, and so on).
if (_wagonInventory.getItemAt(x).Quantity <=
_inventoryNeededForRed || _wagonInventory.getItemAt(x).Quantity <
_wagonInventory.getItemAt(x).Parts)
{
this["binCanvas" + x].setStyle("backgroundColor", 0xCC0000);
}
else statement after the closing curly brace._wagonInventory is greater than the _inventoryNeededForRed variable and (double ampersand &&) the quantity in _wagonInventory is less than or equal to the _inventoryNeededForYellow variable.Note: If the bin quantity on hand is greater than the total inventory needed for the red threshold and the bin quantity on hand is less than or equal the total inventory needed for the yellow threshold, then you have enough inventory to create a wagon, but you will fall within the yellow threshold.
if (...)
{
this["binCanvas"+x].setStyle("backgroundColor", 0xCC0000);
}
else if (_wagonInventory.getItemAt(x).Quantity > _inventoryNeededForRed
&& _wagonInventory.getItemAt(x).Quantity <= _inventoryNeededForYellow)
{
}
else if (_wagonInventory.getItemAt(x).Quantity >
_inventoryNeededForRed && _wagonInventory.getItemAt(x).Quantity <=
_inventoryNeededForYellow)
{
this["binCanvas"+x].setStyle("backgroundColor", 0xE5E006);
}
else statement after the else if statement and use the setStyle() function to set the backgroundColor to green (0x339933) for the dynamic instance of the current bin canvas container. If the available inventory does not fall within the red or yellow thresholds, the bin color should be green.Your code should appear as follows:
if (...)
{
this["binCanvas"+x].setStyle("backgroundColor", 0xCC0000);
}
else if (...)
{
this["binCanvas"+x].setStyle("backgroundColor", 0xE5E006);
}
else
{
this["binCanvas"+x].setStyle("backgroundColor", 0x339933);
}
In this section, you will change the quantity values to see the bin colors change.
49 and click Enter.You should see the handles bin turn yellow (see Figure 7).
In this tutorial you learned how to write ActionScript. You also created an ArrayCollection instance and bound its data to various Flex controls. Lastly, you added a listener to call an event handler that changed the inventory bin displays to red, yellow or green depending on the available inventory.
If you are interested in learning more about the topics in this tutorial, refer to the following resources:
In Part 4, you will learn how to create a custom component in MXML, create class properties with getter and setter functions and use the custom component within an application.
For your reference, here are all the parts in this series: