I have 2 seperate arrays declared, where the corresponding index of each array is "information" about a person.
var alderArr: Array = [45, 34, 18, 12, 27];
var navnArr: Array = ["N. Linjesæter", "P. Kurverud", "O. Sirkelstad", "J. Rektangelsen", "M. Ellipsen"];
Then i also have 2 different input fields where the user can input information that will get added to the array when the button btnLeggTill
is pressed. And the arrays seem to update based on the trace(alderArr + "\n" + navnArr)
btnLeggTil.addEventListener(MouseEvent.CLICK, leggTil);
function leggTil(evt:MouseEvent) {
var nyttNavn: String = txtNavn.text;
var nyAlder: int = int(txtAlder.text);
//trace(nyttNavn + nyAlder); Debug
alderArr.push(nyAlder);
navnArr.push(nyttNavn);
trace(alderArr + "\n" + navnArr);
}//leggTil()
for (var i:int = 0; i < alderArr.length; i++) {
textArea.text += navnArr[i] + ", Alder: " + alderArr[i] + "\n";
}//for
But the information does not seem to update in the textArea. This is basically what I want to accomplish. I want to make it so that when the user inputs new information and new things are added in the array, the textArea will also be updated so it displays this information to the user.
I have 2 seperate arrays declared
While it certainly gets the job done, it's far from ideal. Splitting data that belongs together over several data structures means that you have to keep both arrays in sync.
A better way to model your data is to create a class for it. It's not too difficult, an obvious name would be Person
. According to your code, a person has two properties: age
and name
. Save the following into a file named Person.as
to get started.
package
{
public class Person
{
private var name:String;
private var age:int;
public function Person(name:String, age:int)
{
this.name = name;
this.age = age;
}
}
}
The advantages are that you can perform all kinds of sanity checks (on the given parameters and that you can add all kinds of functionality to it.
Speaking of functionality, add a toString()
method, which returns a String
representation of the object.
package
{
public class Person
{
private var name:String;
private var age:int;
public function Person(name:String, age:int)
{
this.name = name;
this.age = age;
}
public function toString():String
{
return name + ", Alder: " + age;
}
}
}
You can use that class to create objects, which can be passed to trace()
to output them as a String
according to the above function:
var person:Person = new Person("Jack", 35);
trace(person); //Jack, Alder: 35
Now you could have a single Array
of Person
objects. That's much more intuitive. But there's a problem with Array
...
But the information does not seem to update in the textArea
That's true. The TextArea
is a rather simple component. Just to be clear here, we are talking about Flash's fl.controls.TextArea
.
It's more or less just a TextField
. It has no way of asking an array if it was updated (an element added, for example) and an Array
has no way of telling anybody that it was updated.
The problem is usually solved by having something other than Array
, which can tell if it just got changed. One class capable of doing that is DataProvider
, specifically fl.data.DataProvider
.
Instead of storing Person
objects in an Array
, you store them in a DataProvider
on your main timeline:
var people:DataProvider = new DataProvider();
people.addItem(new Person("Jack", 35));
people.addItem(new Person("Jane", 20));
people.addItem(new Person("Charlie", 25));
for (var i:int = 0; i < people.length; ++i)
{
trace(people.getItemAt(i));
}
This adds some dummy data and uses a for
loop to trace()
all items.
To join the elements to a string more easily, you can also get an Array
representation from the DataProvider
and call its join()
method:
var people:DataProvider = new DataProvider();
people.addItem(new Person("Jack", 35));
people.addItem(new Person("Jane", 20));
people.addItem(new Person("Charlie", 25));
trace(people.toArray().join("\n"));
To inform others about the change of data, the DataProvider
dispatches a fl.events.DataChangeEvent
of type DATA_CHANGE
. Add a listener for that event to update the TextArea
accordingly:
var people:DataProvider = new DataProvider();
people.addEventListener(DataChangeEvent.DATA_CHANGE, onDataChange);
function onDataChange(e:DataChangeEvent):void
{
textArea.text = people.toArray().join("\n");
}
people.addItem(new Person("Jack", 35));
people.addItem(new Person("Jane", 20));
people.addItem(new Person("Charlie", 25));
Whenever you add (or remove) something from the DataProvider
, the event fires and textArea
is updated. In your code, this could look like this:
var people:DataProvider = new DataProvider();
people.addEventListener(DataChangeEvent.DATA_CHANGE, onPeopleDataChanged);
function onPeopleDataChanged(e:DataChangeEvent):void
{
textArea.text = people.toArray().join("\n");
}
addPersonButton.addEventListener(MouseEvent.CLICK, addPerson);
function addPerson(e:MouseEvent):void
{
people.addItem(new Person(nameInput.text, int(ageInput.text)));
}
I changed your variable names. ALWAYS use English identifiers in your programming. It's a major pain to read your code without knowing what a leggTil is. If you ask people on the internet for help, use English. If I first have to come up with the elvish word for friend before understanding your code, chances are I'll be eaten by a giant octopus before being able to help you. It is in your own interest to make your code as easy to digest as possible.
Also note that I removed the local variables. There's no real need for them and they only bloat the code. With functionality in the Person
class, the code is really slim now. It almost reads like human lanugage: "add an item to people which is a new person with given name and age"
The DataProvider
works even better with other classes than TextArea
.
In my answer, I only demonstrate how to make the Array
smarter. But there are other things similar to TextArea
that are smarter, too. Some components can be passed a DataProvider
directly. They add the listener to themselves and wire up the functionality to update their text when the DataProvider
changes. If you do not explicitly have to useTextArea
, I recommend using ComboBox
, DataGrid
, List
or TileList
component. Here's an article on how to make them work with a DataProvider