There are two ways to share data between a Flex 4 Spark component and its skin: you can either pull the data from the component into the skin or you can push the data to the skin from the component. It’s a subtle difference, but the latter approach is recommended because it does not rely on data binding, and it promotes encapsulation.
A while back I shared an example of using Flex 4 to create a text input that supports displaying a prompt when it is not focused and no text has been entered. In that example the skin pulled the value of the promptText
property from the hostComponent
and applied it to a SimpleText component with the id “promptView”. The logic for whether or not the promptView
was visible was based on the current state of the skin (focused or normal) and whether or not the hostComponent's
text property was an empty string. This is fine, sort of, but since a good component should be easy to skin, it would be better if the person creating the skin didn’t have to set the label on the promptView or replicate the logic to hide/show it. Because components are aware of the data type of each skin part, it is possible to push data into the skin from the component and encapsulate more of the logic.
I was getting a little tripped up there trying to explain that, but hopefully looking at the two examples side by side will make it more clear.
Example 1 is basically the same as the example created in my earlier post, but cleaned up a little. In this example the skin pulls data from the component.
Example 2 pushes the data from the component into the skin. You’ll see there’s a bit of added complexity in the component now, but the skin is much simpler. I believe this is a better approach and allows developers to use the skin in their own applications much easier.
Both examples have view source enabled, and you can grab also grab the source at github.
13 Comments
Hey Andy,
Thanks for the great example. May I ask what version of the sdk you used to compile it? It doesn’t seem to work when I compile with the version that comes with Flash Builder Beta.
Thanks,
Justin
Hi There,
I’m trying your component (on flex 4.0.0.9237) and get this error message:
‘1119: Access of possibly undefined property textView through a reference with static type AHTextInput. AHTextInput.as TestWeb/src line 29 Flex Problem’
can you help me with this?
I used the version that came with the SDK. I was never able to successfully get any of the nightly builds working.
The Flex team has renamed a bunch of things in the SDK. textView is now called textDisplay or something.
http://opensource.adobe.com/wiki/display/flexsdk/Rename+List
andy, you are right, they change lots of name and make me confused many times. Thank you for sharing the link.
nice post. good example of a common design issue in flex 4. one question: where is spark.primitives.SimpleText??
This should explain what happened to SimpleText:
http://opensource.adobe.com/wiki/display/flexsdk/Spark+Text+Primitives+Decision
To make this work with the non-beta Flex 4 you have to do:
- replace SimpleText with Spark Label in the Component
- replace SimpleText with Spark Label in the Skin
- rename textView in the Skin to textDisplay
- some lines are in the sourceView cut off, so you have to change “Binable]” to “[Bindable" and "SkinState"focused")];” to “[SkinState("focused")];” and so on…
after these steps the AdvancedTextInput should work like expected.
btw: Thanks for the nice component
Really great post and component, but please update it to use textDisplay and Label.
There’s enough misinformation out there that needs to be sifted, and with such a great contribution it’s a shame not to have it up to date. Thank you.
Andy: great component! Thanks for sharing.
Just a note that property
AdvancedTextInput.text
is not longer bindable as theset Text()
was overriden, and the original binding mechanism from base classTextInput
was been restored. Here is the code below to make it work again.Thanks!
[Bindable("change")]
[Bindable("textChanged")]
// Compiler will strip leading and trailing whitespace from text string.
[CollapseWhiteSpace]
override public function set text(value:String):void
{
super.text = value;
if (promptView && text == "")
{
promptView.visible = true;
}
// Trigger bindings to textChanged.
dispatchEvent(new Event("textChanged"));
}
Hi Andy: could you please correct the typo in my previous post? “was been restored” should read “was not restored”. Thanks a lot! I did not re-read myself when I edited the past tense.
–Didier
A last modification to the
set text()
method would allow the programmatic setting of thetext
property (vs. via user input.) Now the prompt stays over in that case, and the visibility of the prompt needs to be turned off manually.Here is the code update:
[Bindable("change")]
[Bindable("textChanged")]
// Compiler will strip leading and trailing whitespace from text string.
[CollapseWhiteSpace]
override public function set text(value:String):void
{
super.text = value;
if (promptView)
{
promptView.visible = (text == "");
}
// Trigger bindings to textChanged.
dispatchEvent(new Event("textChanged"));
}
Thanks,
–Didier
Even with the changes listed in the comment I was not able to get this to work properly.
It won’t focus.
One Trackback
[...] a year ago, while the Flex 4 ground was still moving, Andy Mcintosh blogged a well done prompting text input done with spark components and skinning. As a few people have noted in the comments to that blog, [...]