multiple elements with same ID? Extra data?
Shadowstep33 opened this issue · comments
Hi, will properties I define explicitly be maintained? For example:
{
id: 'hello-world',
component: 'Button',
data: "Mydatastr"
...
}
can I access EZGUI.components['hello-world'].data? Also, if I have the same menu that will create an element with a unique id, I may not know the id ahead of time. For example:
{
id: 'hello-world-'+id,
component: 'Button',
data: "Mydatastr"
...
}
so adding a handler becomes a bit hard, considering I either need to add the handler at run time, which it seems is not the best way if you're trying to be modular and allow a general "create menu" function to do all the repetitive work or know the id of the object the button pertains too (which in my case, defeats the purpose of clicking the button :) ). If i left the id as hello-world an just recreated the menu, will EZGUI.components['hello-world'] get overwritten by the new instance?
I worked around that by creating the menu (in my case a details menu that opens on click) as soon as the item is being clicked. This way, the menu will always have the same ID and can only exists once at a time and will be re-created the next time.
The menu items have a label and a callback property (dynamically created), and all have a click event handler on them. Clicking an item simply executes the corresponding callback attached to that specific item. Since the event handler now listens to that item, you no longer need to keep track of IDs.
Note: In order to make dynamically created components interactive (able to listen for events), you must explicitly create them. Rebuilding is not enough, you have to destroy and create the menu each time you change it. I also figured that certain components, like Label, don't listen to events.
And you can indeed access components with their ID through EZGUI.components[component_id]
. Dynamically editing one of these settings, for example background
, requires you to rebuild()
that component, or completely destroy and create them with event handlers attached. You could try to console.log(EZGUI.components[component_id]);
to see where your attributes are hiding.
There is a specific configuration field to store custom data, it's called userData, this field is made available at the control level, and will be untouched by EZGUI internals.
there is an advanced usage example here
Gui definition : https://github.com/Ezelia/EZGUI/blob/master/examples/game/game-gui.js
Pixi usage : https://github.com/Ezelia/EZGUI/blob/master/examples/game/pixi.html
Phaser usage : https://github.com/Ezelia/EZGUI/blob/master/examples/game/phaser-2.4.html
the user data here is used to store the level id, so we can use only one event for all levels list children.
EZGUI.components.levelsList.bindChildren('click', function (event, me) {
//wait for animation to finish
setTimeout(function () {
levelSelectScreen.visible = false;
fakeGameScreen.visible = true;
EZGUI.components.gameLabel.text = 'Selected ' + me.userData;
}, 150);
//console.log('clicked', event, me.guiID);
});
userData can hold any serializable data type : string, number, array, and json
I thought that I had replied to this issue but guess not:
You could try to console.log(EZGUI.components[component_id]); to see where your attributes are hiding.
Yes I did this and found that any properties I add are in this.settings, not sure if that's intentional or just a inherent side effect (and bad practice for developers to use)
Since the event handler now listens to that item, you no longer need to keep track of IDs.
I like this a lot, much more OOP though the user set parameters on menus is actually probably the path of least resistance here. My menus get recreated on draw already, the problem of different ids arises because my menu handlers are applied in a separate constructor function that is meant to be somewhat modular.
Thanks yall
Hi, sorry to re-open this but just wanted to quickly ask a question pertaining to this task initially:
is there a config property I can use to attach a click handler to a button? I'm still a bit unclear on this
{
id: 'Bleep',
component: 'Button',
onClick: function(){ .... }
}
no and there is reason for this.
the configuration template is aimed to be json data only. this is useful if you want to store your GUI templates in separate files, or store them in the server side so they are updated automatically ...etc
if you add code to json, it can't be stored as separate .json file, the format will be invalid, or we'll need to use eval() to parse it, and this is a bad idea.
I understand your question and I can see some scenarios where it can be useful, but it's still a good idea to separate code from presentation, this is one of the main goals of EZGUI.
Thanks for another great explanation. Makes sense.
I could see a way of possible setting up hooks or routes for developers to latch their code on to. I'd say kind of how Wordpress does it but event listeners and emitters is nothing new in the JS scene lol. More specifically, pointing an element to a pre-defined programmatic snippet. So for example,
{
id: 'bleep-btn',
onClick: 'bloop'
...
}
bloop would be defined in the code and multiple elements could reference bloop. I'm not sure the optimal way to handle passing parameters there but this would promote easier assignment of event handlers and re-usability of code.
The main problem/annoyance for me is essentially having to bind a function after creation of a button. It would be much easier (code cleanliness wise) if it were possible to just set it and forget it when it comes down to events (though, while still trying to maintain separation of code and presentation)
Closing ticket as you answered my question though I'm down to discuss this topic more if you find it promising/viable