In most of the Flex apps written these days there’s a need for applicattion level configuration data. It’s really nice to have this data sit in an XML file on a server somewhere so that it’s really easy to update. Typically I’m seeing stuff in these files like Copyright info, Terms of Service, maybe some other dynamic text for the UI, versioning and managing deprecation.. etc. All of this data is technically read only, so it’s nice to put it in a model that’s read only.
What I found out recently was that binding will only fire if there is both a getter and a setter. So, here’s how I tackled it.
package { [Bindable] public class MyReadOnlyConfigModel { //---------------------------------- // copyrightText //---------------------------------- /** * Legal mumbo jumbo to show for copyright stuff. */ public function get copyrightText() : String { return this._copyrightText; } private function set copyrightText(text : String) : void { this._copyrightText = text; } private var _copyrightText : String = null; //---------------------------------- // setData //---------------------------------- /** * Sets the properties of MyReadOnlyConfigModel */ public function setData(xml : XML) : void { this.copyrightText = xml.copyrightText; } } }
The cool thing about this approach is that the data in the model cannot be written over, but binding will still fire and allow UI components to update automatically when the data is loaded.
If you solved this problem with another solution, I’d love to hear about it.
Props to Andy for giving me the info on this one.
Here’s a quick test app to see it in action:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> <mx:VBox> <mx:Text text="{model.copyrightText}" /> <mx:Button label="set data" click="{model.setData(this.xml);}" /> </mx:VBox> <mx:Script> <![CDATA[ [Bindable] private var model : MyReadOnlyConfigModel = new MyReadOnlyConfigModel(); private var xml : XML = <xml> <copyrightText>this is a copyright</copyrightText> </xml> ]]> </mx:Script> </mx:Application>
If you really want the model read only, why are you setting _copyright in the setter?
A more fool-proof way would be to just set _copyrightText in the setData(), then fire off this:
dispatchEvent(new Event(“propertyChange”));
Which tells bindings to update. Get rid of the setter if you really intend for it to be read-only. (personally, I put in log statements that warn that the value is being thrown away)
Yeah, that’s totally valid too and it’s exactly what the private setter does behind the scenes. Making the setter private ensures that the model is read-only. I think it’s just a matter of style.
thanks for commenting.. good to see both approaches.
AFAIK, you cannot use setter and getter defined in a different scope of visibility because of the bug 174646 in “mxmlc” compiler documented here:
http://kb.adobe.com/selfservice/viewContent.do?externalId=4a146409&sliceId=2
“If a class contains accessor functions with different access control namespace attributes, (for example, aprotected setter and a public getter) using one of them causes a compile-time-error, for example,Compiler-Error 1000: Ambiguous reference to myVar”
The workaround is to rename your getter or setter function to avoid the mismatch
Interesting.. thanks for the comment. I’m using the Flex 3 SDK primarily, so maybe that bug is fixed the new compiler.
Thanks Adam, making the setter private was a diamond bullet..!
rob