View Full Version : Clarification on the scope for "id" attribute
dsalama
06-01-2006, 02:40 PM
As I've read on the documentation, specifying an "id" attribute means that name will be global to the entire application.
The question I have is if I define an element of a class with an "id" attribute. Will it have a global name as well or will that be global to the class itself?
What would happen if I instantiated multiple objects of the class which contained an element with an "id" name specified?
Basically, if I do something like this:
<canvas width="100%" height="100%" debug="true">
<class name="MyClass">
<view id="small" width="50" height="50" bgcolor="red" />
</class>
<MyClass name="class1">
<method event="oninit">
small.setBGColor("blue");
</method>
</MyClass>
<MyClass name="class2">
<method event="oninit">
small.setBGColor("green");
</method>
</MyClass>
<simplelayout axis="x" spacing="10" />
</canvas>
When I run this, it works but complaints with the following warning:
WARNING: Redefining #small from #small to «LzView#1»
Executing some commands on the debugger:
lzx> small
«LzView#1| #small»
lzx> class1.subviews
«Array(1)#9| [LzView id: small ]»
lzx> class2.subviews
«Array(1)#10| [LzView id: small ]»
lzx> class1.small
WARNING: interactive-eval-10: reference to undefined property 'small'
So, when asking for "small" which returns an object, what is it returning? Which one?
Why couldn't I query class1.small, being that small is an element of class1. It should have returned with an LzView object.
Can someone explain this?
The reason I'm asking is because I'm defining some classes and sometimes it becomes a pain trying to reference an element deep in the class lexical hierarchy, so I thought I could use "id" within the class and that would be scoped within the class.
Thanks,
Daniel
cosval
06-02-2006, 03:25 AM
Try not to use ids inside classes, because the "id" attribute should be unique in the entire lzx code. Instantiating the class in more than one objects, you duplicate the id attribute. Use the attribute "name" instead.
dsalama
06-02-2006, 04:34 AM
Yes, but I was trying to avoid having code like window.outerframe.messagespanel.message.header.set Attribute ... in class methods
Thanks,
Daniel
notzippy
06-02-2006, 07:08 AM
Dont forget about the "classroot" and "immediateparent" shortcuts...
bfagan
06-02-2006, 09:32 AM
You could do it like this:
<canvas width="100%" height="100%" debug="true">
<class name="MyClass">
<view name="small" width="50" height="50" bgcolor="red" />
</class>
<MyClass id="class1">
<method event="oninit">
small.setBGColor("blue");
</method>
</MyClass>
<MyClass id="class2">
<method event="oninit">
small.setBGColor("green");
</method>
</MyClass>
<simplelayout axis="x" spacing="10" />
</canvas>
but I would:
<canvas width="100%" height="100%" debug="true">
<class name="MyClass">
<attribute name="smallbgcolor" type="color" value="red" />
<view name="small" width="50" height="50" bgcolor="${classroot.smallbgcolor}" />
</class>
<MyClass name="class1" smallbgcolor="green" />
<MyClass name="class2" smallbgcolor="blue" />
<MyClass />
<simplelayout axis="x" spacing="10" />
</canvas>
dsalama
06-02-2006, 12:07 PM
Yes, but I wasn't that concerned with identifying the outermost element, which in your case is MyClass.
I have a class with many nested elements. However, upon the class initialization, I need to make some changes to attributes of elements beneath. Since instantiation occurs from inside out, all the inner elements are initialized before the class's oninit is reached.
In my class's oninit handler, I have something like window.outerframe.messagespanel.message.header.set Attribute... and as you can see it can become a pain. I was wondering if I could just assign an id to, maybe, the message element within the class so I could refer to it by simply message.header.setAttribute...
The alternative I though of would be something like:
<class name="MyClass">
<attribute name="header" value="null" />
<view name="frame" width="50" height="50">
<view name="_header" width="${parent.width}" height="${parent.height}">
<method event="oninit">
classroot.header = this;
</method>
</view>
</view>
</class>
and then be able to instantiate like this:
<MyClass name="class1">
<method event="oninit">
header.setBGColor("red");
</method>
</MyClass>
It's somewhat of a hibrid approach from your suggestion.
Any comments/suggestions?
Thanks,
Daniel
bfagan
06-02-2006, 12:34 PM
Why is it you feel you need to manually set the bgcolor attribute?
The init order isn't relevent to attribute="${something}". Using ${} defaults to the attribute evaluation time of always not once. Please refer to the following:
http://www.openlaszlo.org/lps-latest/docs/guide/methods-events-attributes.html#d0e15335
dsalama
06-02-2006, 12:37 PM
Sorry for not being that clear before. I'm using bgcolor as an example. That is a trivial example. However, the real need is that I fetch data dynamically from a remote server that feeds me information that I use to adjust attributes of elements in my view. They could be bgcolor, width, height, datapath, or even custom attributes I've defined.
That's the reason I want to find an easier way to reference elements deeply nested within the lexical hierarchy.
Thanks,
Daniel
bfagan
06-02-2006, 12:57 PM
Certainly, you can do things like:
oninit="classroot.setAttribute('formprofile',this)"
I use that frequently.
Consider that if you do something like this:
<canvas width="100%" height="100%" debug="true">
<class name="MyClass">
<attribute name="smallbgcolor" type="color" value="red" />
<attribute name="headercolor" type="color" value="0xcccccc" />
<attribute name="headertitle" type="string" value="foobar" />
<attribute name="headerwidth" type="number" value="50" />
<attribute name="headerheight" type="number" value="20" />
<view name="small" width="50" height="50"
bgcolor="${classroot.smallbgcolor}">
<view name="header" bgcolor="${classroot.headercolor}"
width="${classroot.headerwidth}"
height="${classroot.headerheight}">
<text text="${classroot.headertitle}" resize="true"
fontstyle="bold" />
</view>
</view>
</class>
<MyClass name="class1" smallbgcolor="green" headertitle="test1"
headercolor="0xffcc88" />
<MyClass name="class2" smallbgcolor="blue" />
<MyClass />
<simplelayout axis="x" spacing="10" />
<method event="oninit">
new MyClass(this, {headertitle:'test4',smallbgcolor:0x33ccff});
</method>
</canvas>
You have default attribute values set all in one convenient location. You can programmatically construct a new instance of the class in one line of code. It will be much easier to refactor your code if you start out this way IMHO.
dsalama
06-02-2006, 01:13 PM
Yeah, I guess you're right. It's better to do it that way.
Thanks,
Daniel
vBulletin® v3.8.4, Copyright ©2000-2012, Jelsoft Enterprises Ltd.