tags:

views:

482

answers:

4
<mx:DataGrid x="10" y="10" width="180" height="302" id="dgActions" dataProvider="{actionCollection}">
   <mx:columns>
      <mx:DataGridColumn headerText="Action" dataField="name"/>
         <mx:DataGridColumn headerText="" dataField="setting"  width="30" rendererIsEditor="true"> 
         <mx:itemRenderer >
            <mx:Component>
               <mx:Box width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
                  <mx:CheckBox selected="{data.setting}" click="setActionSetting()">
                     <mx:Script>
                       <![CDATA[
                        private function setActionSetting(){
                           data.setting = String(this.selected);
                        }
                        ]]>
                     </mx:Script>
                  </mx:CheckBox>
               </mx:Box>
            </mx:Component>
         </mx:itemRenderer>
      </mx:DataGridColumn>
   </mx:columns>
</mx:DataGrid>

For some reason I'm getting an error at the data.setting= String(this.selected) line which says "Access to possibly indefined property selected through a reference with static type".

[edit] The solution to the above problem (albeit not the entire mess) was that once you're inside a <mx:Component> tag you are within the scope of said component. To get access to the script and nodes outside this component you have to use the outerDocument object. [end edit]

I'm not sure what it's expecting, I'm assuming that it's going to pass the true/false value of the selected(ness) of the checkbox into the method, but it appears not to understand what "this" is, in this context.

Am I doing something obviously wrong? All I want is for the data source to reflect the change in the status that it initially fed into the checkbox.

EDIT: I just noticed that when I add trace('foo') to the function, it never writes anything back to the console. Is the checkbox's native behavior (and event capture) preventing it from bubbling past to my function?

Additionally, when I add references to objects outside in the rest of the document, it tells me it doesn't recognize them. I'm totally confused as to how Flex scopes things... any additional guidance or links to reference would be really handy.

A: 

If I had to guess "this" is the mx:Script element, try "parent.selected".

UltimateBrent
Actually, `this` refers to the instance of the class, which is the CheckBox in this example. So this is correct, though unnecessary.
Eric Belair
A: 

CheckBox.selected requires a Boolean value. The fact that you're setting data.setting to a String value tells me that data.setting is NOT a Boolean.

Eric Belair
no no.. it is a boolean and the checkboxes are all being rendered in the correct state (based on the data being provided), some on, some off.
Dr.Dredel
+1  A: 

this in this (ha) case is referring to the component renderer and not the surrounding class (or the checkbox, datagridcolumn, datagrid, etc). You are really better off breaking the renderer out into a real component so you won't be obfuscating the scope as much as when the inline component approach is used.

Peter Ent's series on itemRenderers is extremely useful and should explain everything you want to know on the subject.

Joel Hooks
you wouldn't happen to have a link to an example of this, by any chance would you? I'm new to Flex and am not clear on what exactly you're recommending that I do.
Dr.Dredel
I added a link to **the** definitive resource on item renderers in Flex.
Joel Hooks
thanks, the link is very helpful, I have revised my question and posted my own answer which clears everything up.
Dr.Dredel
A: 

so, after a great deal of agony I have finally figured out how this all works....

Joel is on the right track, this doesn't refer to what you would hope it would refer to (namely the checkbox). Additionally, even if you pass this into the method FROM the checkbox node, it refers to the parent wrapper class and not the checkbox itself. So, the solution is to pass in the event, and then access its target, which FINALLY is the checkbox. And then you're home.

In other words...

<mx:CheckBox  selected="{data.setting}" click="setActionSetting(event)">
                     <mx:Script>
                      <![CDATA[                    
                       private function setActionSetting(e:Event):void{
                        data.setting = e.target.selected;

                        trace("n=" + data.name + " set to " + data.setting);
                    //the name is the other piece of the data that I omitted for clarity

                       }
                      ]]>
                     </mx:Script>
                    </mx:CheckBox>
Dr.Dredel
I still think it is an ultimately poor solution to use inline components outside of only the simplest of use cases (this not meeting that requirement). It causes so many odd scope issues, or not so much odd as hard to debug, and creating proper item renderer components makes the code so much easier to mange if you need to come back to it at any time.
Joel Hooks
ok, but I'm still unclear on what you're recommending as an alternative. Also, I don't see what's complicated here... there's a boolean data value that feeds the checkbox and is married to it, so when the checkbox is checked the data source's value reflects the change (and communicates it back to the server).
Dr.Dredel