Update Label text field - actionscript-3

I use a Label component to display the length of an ArrayCollection. How do I get it to update when I add new items to the collection?
Here's the text field for the Label:
text="{model.meetingInfo.documentList.length}"
Here's the handler for adding a new item to the collection:
var attachmentProgressVO:AttachmentProgressVO = new AttachmentProgressVO();
attachmentProgressVO.fileReference = file as File;
newAttachmentList.addItem(attachmentProgressVO);
checkIfUpdate(file as File, attachmentProgressVO);
meetingInfo.docsAndAttachmentsList.addItem(attachmentProgressVO);
I tried adding these 2 lines but that didn't work:
meetingInfo.docsAndAttachmentsList.itemUpdated( attachmentProgressVO );
meetingInfo.docsAndAttachmentsList.refresh();
I also tried changing this:
public var docsAndAttachmentsList:ArrayCollection = new ArrayCollection();
to this:
private var _docsAndAttachmentsList:ArrayCollection = new ArrayCollection();
..with a getter and setter but that didn't work.
I'm not using the right approach, am I?

Generically, Binding only looks at a specific object; you can't drill down 4 objects deep to a specific property and expect binding to update values.
Changing the documentList does not change meetingInfo or Model, so binding will never be triggered. itemUpdated() and refresh() should update the list based class which displays the data; but will not affect your label displaying the count.
You need to listen on the collection for a collectionChange event and manually update the label's text in the collectionChange handler.

Related

Set private var string from input text

The other day I tried setting a string var inside flash, I need somehow to set the var as the text box. I tried doing this:
private var name: String = fromthis.text;
and it doesn't work, anyone knows why?
If I guess the question correctly:
private var name: String = fromthis.text;
means that you declare a variable called name and make its value equal to fromthis.text at that very moment. If you type something into fromthis, it doesn't change the name variable. You need to listen to TextFiled CHANGE event to keep the variable up to date.
update:
You are getting Error #1009 because fromthis is not visible from where you declare the name variable and so it is equal to null, which can't have any fields (including field called text), so you are getting this error.
It may happen becuase it is not yet created at that moment or because the code is located inside of an .as class file and fromthis is located on the stage itself and thus can not be accessed like this.
update 2:
If name is located in a class file, and fromthis is just dragged into the stage in the editor, the best way would be to just pass it to the class constructor:
private var _tf:TextField;
function MyClass(tf:TextField){
_tf = tf;
//or if you need the string from textfield just once you may pass that string
}
And call the class constructor new MyClass(fromthis) (assuming you have access to fromthis at where you instantiate your class).

Flex Dropdownlist dataprovider reset on refresh

I have couple of dropdownlist controls, that shares the same dataprovider(same reference).
I had overridden the set dataprovider method for a sort function.(code below). The issue is that, when I set this shared dataprovider to a new dropdownlist, all the existing dropdown contorls sharing the dataprvider gets unselected(loses its previously selected values).
override public function set dataProvider(value:IList):void{
if(value is ArrayCollection){
var sort:Sort=new Sort();
var sortField:SortField = new SortField();
sortField.numeric=false;
sort.fields=[sortField];
ArrayCollection(value).sort=sort;
ArrayCollection(value).refresh();
}
super.dataProvider=value;
}
There are a ton of isues sharing the dataProvider between components. We've run into this with a lot of clients using our AutoCompleteComboBox.
You can easily use the same source, but a different--separate--collection for each of your dataProviders.
var dataProvider1 :ArrayCollection = new ArrayCollection(someArray);
var dataProvider2 :ArrayCollection = new ArrayCollection(someArray);
var dataProvider3 :ArrayCollection = new ArrayCollection(someArray);
Each collection is just a wrapper around the base source. Sorting one will not affect any of the others, leaving your other ComboBoxes or DropDownLists untouched.
I did no research on this, but there are two issues/ideas coming up:
if you literally use the same reference to the same arraycollection, you do not need to sort this array more than once (and you actually do this by assigning the same arraycollection more than once)
if it about only single-selection dropdowns, then there is a simple solution:
var oldSelected : TypeOfItem = selectedItem as TypeOfItem;
// do the sort (like in your code)
super.dataProvider=value;
selectedIndex = getItemIndex(oldSelected);

Flex 4.6 Mobile - ItemRenderers and application data

A question about ItemRenderers: let's say I have an ArrayCollection that is my application data sitting inside a global object. I them populate a sparks list with this data, setting the ArrayCollection as the dataProvider.
So each ItemRenderer gets a copy of an item sitting in the array. You can override the "set data" method to set the data something more domain-specific. The problem is that the data is a copy of the original item.
Now let's say we want to add some data to the item while inside the ItemRender. For example, it could call a method on the item telling it to load some details about itself, or maybe we allow the user to modify something on the item.
Obviously, we can't do any of this if we are operating on a copy because it will be thrown away as soon as the ItemRenderer is destroyed and the original object doesn't know anything about what happened.
So what's the best practice? Should I just use the itemIndex of the renderer to pull out the original item from my global array like this:
{globalArrayCollection}.getItemAt(this.itemIndex)
But it seems kind of clunky to me. Is there a best practice for dealing with this?
Not sure I'm following but it sounds like you're looking for a way to get at your item renderer to set/change a value.
You could go about accessing a method on the renderer directly.
In your renderer:
public function setSomeValue(aValue:String):void{
someString = aValue;
}
You would also set the data on your ArrayCollection as well.
To access this method you would use this:
var dataGroup:DataGroup = list.dataGroup;
var itemRenderer:YourItemRenderer = dataGroup.getElementAt(list.selectedIndex) as YourItemRenderer;
itemRenderer.setSomeValue("string");
Hmm, why do you think that original ArrayCollection won't change if you change values in itemRenderer? For me this works and initial ArrayCollection changes.
[Bindable]
protected var model:Model;
override public function set data(value:Object):void
{
super.data = value;
this.model = value as Model;
}
protected function changeValue():void
{
model.value = "newValue";
}
Or am I misunderstood something?

how to get the id from the clicked component

On runtime, I create multiple instants of the Group class, like this:
var groupArtist:Group = new Group();
groupArtist.id = artistXML.id;
groupArtist.width = 150;
groupArtist.height = 170;
groupArtist.clipAndEnableScrolling = true;
groupArtist.layout = new VerticalLayout();
I add an eventlistener:
groupArtist.addEventListener(MouseEvent.CLICK, viewDetails);
This is the eventlistener:
private function viewDetails(event:MouseEvent):void
{
Alert.show(event.target.id);
}
But it's not working. How can I get the id of the clicked Group?
I've checked, and the Id is added correctly to the groupinstances.
Try this:
Alert.show(event.currentTarget.id);
What you're alerting is the "target" that was clicked, and associated in the "MouseEvent.CLICK" event, and you probably want the "currentTarget". As Flex Documentation explains on this, "Every Event object has a target and a currentTarget property that help you to keep track of where it is in the process of propagation. The target property refers to the dispatcher of the event. The currentTarget property refers to the current node that is being examined for event listeners.".
The Most Interesting Man in the World doesn't normally code in Actionscript... but when he does, he uses event.currentTarget.

Change the label text at runtime in flex

i have created a group in run time and then added in it two buttons and one label
addElement (myGroup )
myGroup.addElement ( button 1 )
myGroup.addElement ( label )
myGroup.addElement ( button 2 )
now when i click on one button 2 i can get event.currentTarget.
How can i change the text of label using this event.currentTarget. How can i target the label
I believe this may solve your problem.
When you create the label Object provide it with an id. so that you can access the label through out the application using this 'id'. You can change the text by using this id.text
Or you can use the group objectId. like this one
groupObjectID.getElementAt(index).text
You can see if the event.currentTarget is Label by casting it using 'as' operator
var lbl:Label = event.currentTarget as Label;
if (lbl)
{
//do rest of processing
}
Give name to your Label label.name='lblSomething'. Then you can access by
var mylabel:Label = myGroup.getChildByName(lblSomething) as Label
Try var labelStr:String = event.currentTarget.label;
Actually I do recommend you try to create those labels and buttons as either public or private objects whenever possible so that you can always refer to them using the object ID.
This is a good practice as well... just my 2 cents.
public var t_label:Label = new Label (); // t_ just stands for temporary... nothing special
myGroup.addElement (this.t_label);
Then inside ANY event handler you can write something like this to change the label text.
private function onWhateverHandler (event:Event):void
{
this.t_label.text = "whatever new string value";
}