简体   繁体   中英

Exposing properties to a Spark Skin class

I am having trouble wrapping my head around the spark skin class in relation to it's host component. Basically, from what I've seen with most every skin that comes in the Flex 4 framework they don't directly expose the properties that are dynamically being set in the host component. Instead, they define states that get exposed to the skin class to define when a component should look different. This is all fine and dandy when you have a very simple component with a standard set of states, but when you have twenty different properties (hypothetically) to set in your host component that should change how the skin looks it could get very complicated very fast.

The way that I've seen that they have used to get around this is by overriding the commitproperties and invalidate functions in the skin class, grabbing the values for the properties they want from there, and then setting them to a locally instantiated variable inside the skin class. This is fine, but I feel like that is just a patch workaround to it which makes things a lot more complicated than it needs to be.

HERE'S MY QUESTION: Is there any way to directly expose a bindable property from the host component class so when you define your skin class it is directly ready to be read from? Let's say you have custom button with a boolean property of 'selected'. In the skin class, you want to add in a get and set function for the property 'selected' so you can perform some action upon your skin whenever it's set. How do you tell the skin class that this is an available property for you to work with from the host component?

This question exists at a very theoretical level. I'm not clear what you're trying to accomplish, nor what sort of properties you're setting on your component class. I suspect, there is an architecture problem if you have 20 properties and each one needs to correlate to a different skin states somehow.

However, I can try to answer your specific questions.

 Is there any way to directly expose a bindable property from the 

host component class so when you define your skin class it is directly ready to be read from?

When building Flex MobileSkins, they recommend creating a property named hostComponent which gives the skin class a reference to the component class. MXML skins already have a similar property . If you're using a custom skin, this property is created automatically using the HostComponent metadata. Therefore from the skin class you can access properties on the component class using the hostComponent property.

Let's say you have custom button with a boolean property of 'selected'. In the skin class, you want to add in a get and set function for the property 'selected' so you can perform some action upon your skin whenever it's set.

I'm not envisioning the situation where you would want to do this. Generally you would not define any properties on the skin class which you intend to explicitly change on the instance of the skin class.

You could dispatch an event from the component class when the property changes. [This is very common]. Then listen for that event in the skin class using the hostComponent property and change things there.

There is also a way to access the skin class instance from within the component class. So you could change properties directly on the skin class using the skin property.

I wouldn't follow either approach without thinking it through. Ideally the component class and skin class should be encapsulated from each other; and each approach would provide dependencies.

When you affect a skin to a component, you can use metatags to store a reference to the skin part you actually use :

[SkinPart(required="false")]
public var resizeHandle:UIComponent;

Then, when overriding the partAdded and partRemoved methods, you will be able to set or unset whatever you want in these skin parts, from the basic properties to event listeners.

override protected function partAdded( partName:String, instance:Object):void
{
    super.partAdded(partName, instance);

    if (instance == resizeHandle) {
            resizeHandle.addEventListener(MouseEvent.MOUSE_DOWN, resizeHandle_mouseDownHandler);
    }
}

override protected function partRemoved(partName:String, instance:Object):void
{
    if (instance == resizeHandle) {
        resizeHandle.removeEventListener(MouseEvent.MOUSE_DOWN, esizeHandle_mouseDownHandler);
    }

    super.partRemoved(partName, instance);
}

Furthermore, since you have stored a reference to your skin parts, you can still access it whenever you want in your host component and update it. Am I clear ? :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM