Flex: Method doesn't work when being called on parentDocument - apache-flex

I wonder is anyone can look at this code and tell me why calling the removeSelectedChild works when called from the same document, but returns the following error when called from the child document/component.
"ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller."
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Accordion id="myAccordion"
width="100%" height="100%"
selectedIndex="0">
<mx:Script>
<![CDATA[
public function removeSelectedChild():void {
trace("before");
try {
myAccordion.selectedChild.parent.removeChild(myAccordion.selectedChild)
} catch(err:ReferenceError) {
trace("catch")
}
trace("after");
}
]]>
</mx:Script>
<mx:headerRenderer>
<mx:Component>
<mx:Button click="{ parentDocument.removeSelectedChild() }" />
</mx:Component>
</mx:headerRenderer>
<mx:HBox>
<mx:Button click="{ removeSelectedChild() }" />
</mx:HBox>
</mx:Accordion>
</mx:Application>
Clicking on the button in the child produces the expected result, whilst clicking on the header removes the child as expected but also throws an error despite the fact they both call exactly the same method.
Sorry that the example is a little contrived, this problem arose in a quite complicated view, which was using all kinds of custom components. This was the only way I could display it in a way that will be quick for you to compile and easy to focus on the real issue without background noise.
I'm pulling my hair out on this one and would really appreciate it if anyone could help.
UPDATE: I have now discovered that the exception is fired after the method has finished executing. See the trace statements above. "after" is traced before the exception is thrown.
Cheers,
Chris

As you noted, the error is not being thrown by your function. The default action when clicking on the header of an accordion is to expand or contract that element. Since you're removing the element, when Flex tries to expand or contract it, you get an error.
You can fix it by stopping the event from doing its default action:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Accordion id="myAccordion"
width="100%" height="100%"
selectedIndex="0">
<mx:Script>
<![CDATA[
public function removeSelectedChild(event:MouseEvent):void {
myAccordion.removeChild(myAccordion.selectedChild);
event.stopImmediatePropagation();
}
]]>
</mx:Script>
<mx:headerRenderer>
<mx:Component>
<mx:Button click="{ parentDocument.removeSelectedChild(event) }" />
</mx:Component>
</mx:headerRenderer>
<mx:HBox>
<mx:Button click="{ removeSelectedChild(event) }" />
</mx:HBox>
</mx:Accordion>
</mx:Application>

Not a solution, but perhaps a workaround: could you try rewriting the method like this:
myAccordion.selectedChild.parent.removeChild(myAccordion.selectedChild)
if that doesn't work there must be a bug somewhere in Flex.

Use "outerDocument" instead of "parentDocument". defines a new mini-scope.

Related

Flex: Getting rid of "Warning: Filter will not render. The DisplayObject's filtered dimensions ..." error

When printing (I think at the point I call FlexPrintJob.addObject()) I get the following:
Warning: Filter will not render. The DisplayObject's filtered dimensions (3324, 1740) are too large to be drawn.
I don't know what it thinks is 3324, 1740. The mx:Box object I pass to it is about 600x100.
I'm wondering if this problem is related to another problem I'm having. What gets printed has an extra border on the bottom and the right of what I want printed. I'm hoping that understanding this message will correct my problem.
I'm using the Flex 3.5 SDK
Here's a stripped down version of the code that still allows for this problem:
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
title="FPL Flight Strip"
showCloseButton="true"
borderAlpha="1"
borderColor="{BrandGlobals.COLOUR_DARK}"
borderThicknessBottom="1"
borderThicknessLeft="1"
borderThicknessRight="1"
borderThicknessTop="0"
dropShadowEnabled="true"
fontSize="{AppGlobals.fntSize}"
backgroundAlpha="1.0"
alpha="1.0"
creationComplete="init()"
close="PopUpManager.removePopUp(this);">
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import mx.printing.FlexPrintJobScaleType;
import mx.printing.FlexPrintJob;
private function init():void
{
this.setStyle('fontFamily', 'Arial');
}
private function printData():void
{
var dbPrintJob: FlexPrintJob = new FlexPrintJob();
if (dbPrintJob.start())
{
try
{
dbPrintJob.addObject(boxPrint, FlexPrintJobScaleType.NONE);
}
catch (e:Error)
{
//trace(e);
}
dbPrintJob.send();
}
}
]]></mx:Script>
<mx:VBox width="600" height="100" horizontalAlign="center" verticalAlign="middle" backgroundColor="#FFFFFF" verticalGap="1" paddingLeft="2" paddingRight="2" paddingTop="2" paddingBottom="2">
<mx:Box id="boxPrint" width="100%" height="100%" backgroundColor="#FFFFFF">
<mx:Box id="box" width="100%" height="100%"/>
</mx:Box>
</mx:VBox>
<mx:ControlBar width="100%" barColor="#E8E8E8" paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0">
<mx:VBox width="100%" height="100%" horizontalAlign="left" backgroundColor="#E8E8E8" paddingTop="5" paddingBottom="5" paddingRight="20" paddingLeft="20">
<mx:HBox width="100%" height="100%">
<mx:Button label="Print Strip" fontFamily="Arial" click="printData()" width="100" height="25" />
</mx:HBox>
</mx:VBox>
</mx:ControlBar>
</mx:TitleWindow>
I was not able to reproduce the filter error in Flex 3.6. Are you not able to upgrade? To my knowledge, there shouldn be very few issues with backwards compatibility, unless you are heavily overriding mx_internal.
I did however get the problem with the borders. This has to do with the way you are adding your objects. It's best to wrap the thing you want to print in a container, then add the container to the print job. This let's you control things like margins and spacing.
private function printData():void
{
var dbPrintJob:FlexPrintJob = new FlexPrintJob();
if(dbPrintJob.start())
{
try
{
dbPrintJob.addObject(this.canvas, FlexPrintJobScaleType.NONE);
}
catch(e:Error)
{
//trace(e);
}
dbPrintJob.send();
}
}
<mx:Canvas id="canvas" width="100%" height="100%">
<mx:Box id="boxPrint" top="10" left="10" bottom="10" right="10" backgroundColor="#FFFFFF">
<mx:Box id="box" width="100%" height="100%" />
</mx:Box>
</mx:Canvas>
Use the canvas to paint your background and space the children into the desired print layout.
I would also suggest giving this a quick read:
Setting size, scale, and orientation
You can try using a simple font such as "Arial", and try if the error still appears, to rule out problems than font.
And avoid using any component if you're having this problem to see if that eliminates the problem.

spark List with ItemRenderer click function not working

I am having an issue with my ItemRenderer, which I am using for a spark List. My code is the following:
I have this list:
<s:List
id="productSetList"
dataProvider="{ model.productSets }"
change="model.selectSet( productSetList )"
height="100%" width="100%"
borderVisible="false"
itemRenderer="SideBarItemRenderer" top="20" left="15">
</s:List>
and my itemRenderer is:
<s:ItemRenderer
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
width="160" height="175" autoDrawBackground="false" buttonMode="true" useHandCursor="true"
click="click(event)" cacheAsBitmap="true"
>
<fx:Script>
<![CDATA[
import com.png.vm.model.vos.ProductSet;
protected function click(event:MouseEvent):void
{
trace('arthur');
}
]]>
</fx:Script>
<s:BitmapImage source="{ProductSet(data).image}" width="160" height="175"/>
</s:ItemRenderer>
The thing is, if I scroll the list, and click on an item, it does not trace 'arthur' ! Why is this so ? I must trace that all the time that someone clicks in the list!
EDIT:
If I remove change="model.selectSet( productSetList )" in the list, it works!! but I cannot remove that, some suggestions ? How can I switch that to another function?
Trace only works when you are debugging/using the debugging version of Flash Player. Make sure you are using that. If you want a pop-up message use Alert.show("message")
For more information about trace() check out:
http://livedocs.adobe.com/flex/3/html/help.html?content=logging_08.html
And Alert.show(): http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00001965.html
If you are running debug player. Try originating the click event from an embedded <s:Group> this way whatever you add in here beyond the bitmap will still trigger the click event.
Something like:
<s:Group width="100%" height="100%" click="click(event)" >
<s:BitmapImage source="{ProductSet(data).image}" width="160" height="175"/>
</s:Group>
I've definitely had click events work for me inside of ItemRenderers before
My apologies, I have finally solved it. The problem was that inside the function,model.selectSet, I was calling List.change; I was messing the list up! My function was as follows:
public function selectSet(list:List):void {
list.layout.verticalScrollPosition=100;
// another stuffs
}
So, I just removed the line : list.layout.verticalScrollPosition=100; and now it`s working fine.
Thanks for all the help!

Flex 3: How do I remove a Component Using a Button in the Component

I'd like to use a button within a component to remove it. So, you click it and the component is gone. But, I haven't figured out how you reference the component from within the component. What should I put in click=""?
My component: popCanvas
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel width="200" height="200" title="hello"
click="remove=">
</mx:Panel>
</mx:Canvas>
In the main app:
var popCanvas:PopCanvas= new PopCanvas;
popCanvas.x = 20;
popCanvas.y = 30;
this.addChild(popCanvas);
Any suggestions?
Thank you.
-Laxmidi
Okay,
This is what I came up with:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
public function removeMe(event:MouseEvent):void {
this.removeChild(event.currentTarget as DisplayObject);
}
]]>
</mx:Script>
<mx:Panel width="400" height="300" title="hello" click="removeMe(event)">
</mx:Panel>
</mx:Canvas>
So, I used the event's currentTarget to reference the component in order to remove it. If someone clicks anywhere on the component it's removed.
Thanks.
-Laxmidi

Flex: Components bound to empty ArrayCollection at load time don't render as expected when the ArrayCollection is updated

I'm new to Flex and am using TileList bound to an ArrayCollection. The array collection is empty at load time, and then updates with the results from am HTTPService call. The problem is that the item renderers aren't being rendered as expected, I'm guessing because there was no data when they were first rendered at load time. Here's simplified example:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" >
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var myList1:ArrayCollection = new ArrayCollection();
[Bindable]
public var myList2:ArrayCollection = new ArrayCollection([{item:"foo"}, {item:"bar"}]);
public function updateMyList():void
{
myList1.source = [{item:"foo"}, {item:"bar"}];
}
]]>
</mx:Script>
<mx:Button id="myButton" label="Update My List"
click="updateMyList();"/>
<mx:TileList dataProvider="{myList1}"
direction="vertical"
width="800" >
<mx:itemRenderer>
<mx:Component >
<mx:Canvas backgroundColor="yellow" >
<mx:Label text="{data.item}" width="800" />
</mx:Canvas>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
<!-- This one renders as expected -->
<mx:TileList dataProvider="{myList2}"
direction="vertical"
width="800" >
<mx:itemRenderer>
<mx:Component >
<mx:Canvas backgroundColor="yellow" >
<mx:Label text="{data.item}" width="800" />
</mx:Canvas>
</mx:Component>
</mx:itemRenderer>
</mx:TileList>
</mx:Application>
You will notice that the second TileList whose bindings has data at load time renders as expected (800px wide), bit the first TileList is rendered is not the correct width and has scrollbars around it.
Could anyone explain why this is happening or even provide some work arounds to avoid this?
Regards,
Chris
It's likely that this section is causing the problems:
public function updateMyList():void
{
myList1.source = [{item:"foo"}, {item:"bar"}];
}
From here:
source of data in the ArrayCollection.
The ArrayCollection object does not
represent any changes that you make
directly to the source array. Always
use the ICollectionView or IList
methods to modify the collection.
This property can be used as the
source for data binding. When this
property is modified, it dispatches
the listChanged event.
So I'd probably change the line to:
myList1= new ArrayCollection([{item:"foo"}, {item:"bar"}]);
http://livedocs.adobe.com/flex/3/langref/mx/controls/TileList.html
Check the API.
Set the columnWidth and rowHeight properties like this,
<mx:TileList dataProvider="{myList1}"
direction="vertical"
width="800" columnWidth="800" rowHeight="25">
There is probably a more "proper" way to do it, but that should get you started.

How to call a mxml component from another mxml component in flex-edited

I need to call a component named "defectTracker.mxml" by clicking a link in another mxml component called "reviewComponent.mxml". How do I achieve that?
This is my reviewComponent.mxml code:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%" height="100%"
horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:Script>
<![CDATA[
private function defectTrackerLink(event:Event):void{
//call defectTracker
}
]]>
</mx:Script>
<mx:LinkButton label="Delete" textDecoration="underline" textRollOverColor="blue"/>
<mx:LinkButton label="Defect Tracker" textDecoration="underline" textRollOverColor="blue" click="defectTrackerLink(event)"/>
</mx:VBox>
Some one guide me.
Main.mxml:
<mx:Script>
<![CDATA[
private function subBtnBar(evt:ItemClickEvent):void{
switch (evt.label){
case "IQA/UAT":
this.bdyStack.selectedChild = screenIQA;
break;
case "EQA":
Alert.show("Yet To Design");
break;
case "Review Tracker":
this.bdyStack.selectedChild = reviewTracker;
break;
case "Defect Tracker":
this.bdyStack.selectedChild = defectTracker;
break;
default:
trace ("Neither a or b was selected")
}
}
]]>
</mx:Script>
<mx:ViewStack id="tabView" width="910" creationPolicy="all">
<mx:ToggleButtonBar horizontalGap="0" id="subTabBar"
itemClick="subBtnBar(event);" styleName="SubButtonBar"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}">
<mx:dataProvider>
<mx:String>IQA/UAT</mx:String>
<mx:String>EQA</mx:String>
<mx:String>Review Tracker</mx:String>
<mx:String>Defect Tracker</mx:String>
<mx:String>Defect Configuration</mx:String>
<mx:String>Defect Export</mx:String>
<mx:String>Defect Import</mx:String>
</mx:dataProvider>
</mx:ToggleButtonBar>
</mx:ViewStack>
<mx:ViewStack id="bdyStack" width="910" height="80%">
<components:ScrIQA id="screenIQA"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
<components:scrWorkList id="screenWorkList"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
<components:DefectEntryVerification id="defectEntryVerification"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
width="100%" height="100%"/>
<components:scrDefectResolutionAndCause id="defectResolutionnVerification"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
width="100%" height="100%"/>
<components:reviewTracker id="reviewTracker"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
width="100%" height="100%"/>
<components:defectTracker id="defectTracker"
hideEffect="{dissolveOut}" showEffect="{dissolveIn}"
width="100%" height="100%"/>
</mx:ViewStack>
The defect Tracker scren is already linked with the main mxml file. How to call the function in the reviewComponent file?
reviewComponent consist of 2 link buttons and it is a column entry of the reviewTracker.mxml file's datagrid. So when I click the link in the review component, I want the defectTracker screen to be called. Its already a child of the main.mxml file.
I tried creting an instance of the main file in the component, and changes the selected child to defect tracker, It shows an error saying:
Error #1009: Cannot access a property or method of a null object reference.
My modified reviewComponent.mxml code:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%" height="100%"
horizontalScrollPolicy="off" verticalScrollPolicy="off">
<mx:Script>
<![CDATA[
private function defectTrackerLink(event:Event):void{
var main:Main=new Main();
main.bdyStack.selectedChild=main.defectTracker; }
]]>
</mx:Script>
<mx:LinkButton label="Delete" textDecoration="underline" textRollOverColor="blue"/>
<mx:LinkButton label="Defect Tracker" textDecoration="underline" textRollOverColor="blue" click="defectTrackerLink(event)"/>
</mx:VBox>
Please some one guide me in this? Should I call the item click event function of the Toggle button Bar? If so how to do It?
I would use a custom event that bubbles. You would dispatch it from the reviewComponent and it would be caught by the defectTracker.
Here are some good articles that tell you how to create a custom event and how to use it http://livedocs.adobe.com/flex/3/html/help.html?content=createevents_3.html
http://www.connatserdev.com/blog/?p=86
By calling, do you mean adding it to the VBox?
var dTracker:DefectTracker = new DefectTracker();
addChild(dTracker);
Would calling is with a popup work?
var dTracker:DefectTracker = new DefectTracker();
PopUpManager.addPopUp(dTracker, this, true);

Resources