Copy link to clipboard
Copied
I'm learning how to create custom components and started by developing a test component that correctly creates dynamic parts. So far, so good. Then I tried to move that component into my real project, but when I run it there, createDynamicPartInstance always returns null (which obviously doesn't happen in the test component). I've gone over and over the code, but can't find any differences, aside from the test components having a slightly different name.
Can anyone suggest what the difference may be? I'm at a loss.
Renee
Here are the relevant parts of the real component that isn't working correctly:
package com.leadingstep.components
{
import com.leadingstep.skins.DisplaySentenceSkin;
import mx.collections.*;
import mx.core.IFactory;
import mx.events.Request;
import spark.components.HGroup;
import spark.components.supportClasses.SkinnableComponent;
public class DisplaySentence extends SkinnableComponent
{
[SkinPart(required="true",type="com.leadingstep.components.SentenceWord")]
public var line1Words:IFactory;
[SkinPart(required="true",type="com.leadingstep.components.SentenceWord")]
public var line2Words:IFactory;
[SkinPart(required="true")]
public var line1:HGroup;
[SkinPart(required="true")]
public var line2:HGroup;
public function DisplaySentence()
{
super();
setStyle("skinClass", DisplaySentenceSkin);
}
protected function createLine1Words():void {
for (var i:uint=0; i < 20; i++) {
trace("create line 1 word " + i);
if (createDynamicPartInstance("line1Words") == null) {
trace("create dynamic returned null");
} else {
trace("create dynamic did not return null");
}
}
}
}
And the skin:
<s:Skin 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="com.leadingstep.components.*">
<!-- host component -->
<fx:Metadata>
[HostComponent("com.leadingstep.components.DisplaySentence")]
</fx:Metadata>
<!-- SkinParts
name=line1Words, type=mx.core.IFactory, required=true
name=line2Words, type=mx.core.IFactory, required=true
name=line2, type=spark.components.HGroup, required=true
name=line1, type=spark.components.HGroup, required=true
-->
<fx:Declarations>
<fx:Component id="line1Words" >
<components:SentenceWord skinClass="com.leadingstep.skins.SentenceWordSkin"/>
</fx:Component>
<fx:Component id="line2Words" >
<components:SentenceWord skinClass="com.leadingstep.skins.SentenceWordSkin"/>
</fx:Component>
</fx:Declarations>
<s:VGroup>
<s:HGroup id="line1"/>
<s:HGroup id="line2"/>
</s:VGroup>
</s:Skin>
Copy link to clipboard
Copied
Ok, so I ended up randomly finding the problem. In my partAdded routine, I was missing a semicolon in the line prior to calling super.partAdded(), and that routine is what I use to kick off creating the dynamic parts (i.e., once the relevant line hgroup has been created). I still don't understand why this would cause that particular problem, but the change seems to have cleared things up. Weird because I had the same error in the test component and it worked without any problems. In any case, I'm off and running again.
Copy link to clipboard
Copied
Well, it looks like I spoke too soon. I had seen comments that things can get flaky if you aren't calling the super.xxx routines correctly, so I really did think that was the problem, but soon after I started working on some other issues, the same problem came back. It is definitely flaky, sometimes there and sometimes not, but now I can't get past it again.
I also thought I might try upgrading Flash Builder to see if that helps, but I can't seem to find the right download. I need the plug-in version, but just want to go with the 4.1 SDK/Flash Builder 4.0.1. Every link I try points me to 4.5 instead. I don't want to upgrade to that yet, so specifically want 4.0.1. Can someone point me to the right place with instructions on uninstalling/reinstalling the plug-in on a Mac?
Thanks!
Copy link to clipboard
Copied
It looks like I really have found the problem this time. Thought I would post, just in case it will help anyone else.
I was calling the createLine1Words routine from within the partAdded override function when I received the indication that the line1 part had been added. Apparently, you can't/shouldn't do this. Sometimes it seemed to work, but it's definitely flaky/unreliable and most of the time the calls to createDynamicPartInstance would return null.
I changed the code so that, when I try to set the data for the component, I check to see if the individual word parts/components have been created and if not, I create them then. There must be something about the initialization process for the component that requires the entire process to be complete before you start trying to create the dynamic parts for it.
BTW, I've been using the "Developing Flex 4 Components" book by Mike Jones with all of this and highly recommend it.
Renee
Copy link to clipboard
Copied
@drrevis Thanks for posting your solution. That helped me figure-out what was going wrong with my dynamic part instances.
Copy link to clipboard
Copied
Hi Drrevis,
You are right, we should not rely on the partAdded to add the Dynamic part. From my experience, this process should happen in createChildren() (once all the skin parts have been added to the stage).
Cheers,
Jack