PDA

View Full Version : [CLOSED] IDs of objects



bogc
Dec 06, 2012, 8:11 PM
Hi:

I am just curious how the IDs for components are generated and how the objects are set under the App namespace (which is the default).

Here is some code:

Page.Master



<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Page.master.cs" Inherits="Ext.Net.Examples.Page" %>

<%@ Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test</title>
</head>
<body>
<ext:ResourceManager ID="ResourceManager" runat="server" IDMode="Explicit" ScriptMode="Debug" SourceFormatting="true" Namespace="App"/>

<div>
<asp:ContentPlaceHolder ID="PageContent" runat="server">

</asp:ContentPlaceHolder>
</div>


<script>
Ext.onReady(function () {
debugger;
});

</script>

</body>
</html>

Here is the page:

TestPageWithMaster.aspx


<%@ Page Title="" Language="C#" MasterPageFile="~/Page.Master" AutoEventWireup="true" CodeBehind="TestPageWithMaster.aspx.cs" Inherits="Ext.Net.Examples.Examples.ViewPort.Basic.Built_in_ Markup.TestPageWithMaster" %>


<asp:Content ID="Content1" ContentPlaceHolderID="PageContent" runat="server">

<ext:Viewport ID="Viewport1" runat="server" Layout="fit" IDMode="Explicit">
<Items>
<ext:Panel ID="Panel1"
runat="server"
Title="Some Panel"
Height="150"
BodyPadding="6"
Html="North"
IDMode="Explicit"
/>

</Items>
</ext:Viewport>


</asp:Content>

When this is generated to JavaScript, I get this:


<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link type="text/css" rel="stylesheet" href="/extjs/resources/css/ext-all-gray-embedded-css/ext.axd?v=20533" id="ext-theme" />
<link type="text/css" rel="stylesheet" href="/extnet/resources/css/extnet-all-embedded-css/ext.axd?v=20533" />
<script type="text/javascript" src="/extjs/ext-all-debug-js/ext.axd?v=20533"></script>
<script type="text/javascript" src="/extnet/extnet-all-debug-js/ext.axd?v=20533"></script>

<title></title>

<script type="text/javascript">
//<![CDATA[
Ext.net.ResourceMgr.init({
id: "ctl00$ResourceManager",
theme: "gray"
});Ext.onReady(function(){Ext.create("Ext.Viewport",{
id: "ctl00_PageContent_Viewport1",
renderTo: Ext.getBody(),
items: [
{
id: "ctl00_PageContent_Panel1",
height: 150,
html: "North",
bodyPadding: 6,
title: "Some Panel"
}
],
layout: "fit"
});});
//]]>
</script>
</head>
<body>


<div>






</div>


<script>
Ext.onReady(function () {
debugger;
});

</script>

</body>
</html>


Why is this? Doesn't it contradict the behaviour stated by the Explicit IDMode ? Shouldn't I see the exact IDs I set in the code without the ctl00_PageContent prefix?

If you add App to the watch list you get these members:

- App {...} Object
+ ext-quicktips-tip {...} Object
+ ext-quicktips-tip_header_hd {...} Object
+ ext-quicktips-tip_header {...} Object
+ ctl00_PageContent_Viewport1 {...} Object
+ ctl00_PageContent_Panel1 {...} Object
+ ctl00_PageContent_Panel1_header_hd {...} Object
+ ctl00_PageContent_Panel1_header {...} Object


Who sets the objects under the App namespace? Is it ExtJs or Ext.Net? If it's Ext.Net where exactly is this done? I am trying to understand what names or ids are used to set these objects under the App namespace.


Maybe this is a discussion for another time, but I find that one of the harder things in the Ext.Net is wiring events to JavaScript handlers. I generate my objects in code behind (I like it much better than markup). Usually these handlers belong to a JavaScript controller which is an object that can have additional data. In ExtJs 4 I noticed that they solved the problem by linking controller methods to object events using code like this:



init: function(application) {
this.control({
"#addGridButton": {
click: this.onAddGridButtonClick
},
"#addColumnButton": {
click: this.onAddColumnButtonClick
},
"#removeLastColumnButton": {
click: this.onRemoveLastColumnButtonClick
},
"#refreshButton": {
click: this.onRefreshButtonClick
},
"#updateTemplateButton": {
click: this.onUpdateTemplateButtonClick
}
});
}


onAddGridButtonClick, ... are methods in a class that extends the Controller class.



Ext.define('MyApp.controller.MyController', {
extend: 'Ext.app.Controller',
...
}


ExtJs 4 can also inject getters and setters based on the refs collection:


refs: [
{
ref: 'canvasViewport',
selector: '#canvasViewport'
},
{
ref: 'canvasDateField',
selector: '#canvasDateField'
}
],

This code will inject a getCanvasViewport() method in the controller.

In ExtJs 3/ Ext.Net 1 I solved this problem in a similar way with ExtJs 4, however I relied knowing how Ext.Net injects the objects and the names it uses. In Ext.Net 2 this changed and I am just trying to understand how these IDs are used.

Thanks

bogc
Dec 06, 2012, 9:23 PM
I read #2 in the Breaking changes document (http://examples2.ext.net/#/Getting_Started/Release_Documents/BREAKING_CHANGES/) and I have to use IDMode Static instead of Explicit.

About the other discussion, I know from other threads I read here (for instance this one: http://forums.ext.net/showthread.php?20277-CLOSED-Custom-component-ID-creation-difference-with-v-1-x&highlight=clientid) that you guys don't recommend using ids, however I find them very useful because in the end they become names of the objects and they are a way of accessing them through properties or getters and setters as it is the case in ExtJs 4.

I am still curious about which IDs are used to set the object reference under the App namespace.

Update:

After more testing...

If the ItemID is set then the ItemID is used to set the object reference under the App object.

Changed a bit the sample:
Page.Master


<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Page.master.cs" Inherits="Ext.Net.Examples.Page" %>

<%@ Register assembly="Ext.Net" namespace="Ext.Net" tagprefix="ext" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Test</title>
</head>
<body>
<ext:ResourceManager ID="ResourceManager" runat="server" ScriptMode="Debug" SourceFormatting="true" Namespace="App" IDMode="Predictable"/>
<div>
<asp:ContentPlaceHolder ID="PageContent" runat="server">

</asp:ContentPlaceHolder>
</div>
</body>
</html>



TestPageWithMaster.aspx:


<%@ Page Title="" Language="C#" MasterPageFile="~/Page.Master" AutoEventWireup="true" CodeBehind="TestPageWithMaster.aspx.cs" Inherits="Ext.Net.Examples.Examples.ViewPort.Basic.Built_in_ Markup.TestPageWithMaster" %>


<asp:Content ID="Content1" ContentPlaceHolderID="PageContent" runat="server">
<ext:Viewport ID="Viewport1" runat="server" Layout="fit" >
<Items>
<ext:Panel ID="Panel1"
runat="server"
ItemID="Panel1"
Title="Some Panel"
Height="150"
BodyPadding="6"
Html="North"
>
<Items>
<ext:Button runat="server" Text="Test" ID="testButton" ItemID="testButton" Handler="#{testButton}.onButtonClicked();"></ext:Button>
</Items>
</ext:Panel>
</Items>
</ext:Viewport>
<script>
Ext.onReady(function () {
debugger;
});
</script>
</asp:Content>


This will show:


- App {...} Object
+ ext-quicktips-tip {...} Object
+ ext-quicktips-tip_header_hd {...} Object
+ ext-quicktips-tip_header {...} Object
+ PageContent_Viewport1 {...} Object
+ Panel1 {...} Object
+ testButton {...} Object
+ PageContent_Panel1_header_hd {...} Object
+ PageContent_Panel1_header {...} Object


Note App.testButton. Now here is the problem. The HTML code above gets translated to:


<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link type="text/css" rel="stylesheet" href="/extjs/resources/css/ext-all-gray-embedded-css/ext.axd?v=20533" id="ext-theme" />
<link type="text/css" rel="stylesheet" href="/extnet/resources/css/extnet-all-embedded-css/ext.axd?v=20533" />
<script type="text/javascript" src="/extjs/ext-all-debug-js/ext.axd?v=20533"></script>
<script type="text/javascript" src="/extnet/extnet-all-debug-js/ext.axd?v=20533"></script>

<title></title>

<script type="text/javascript">
//<![CDATA[
Ext.net.ResourceMgr.init({
id: "ctl00$ResourceManager",
theme: "gray"
});Ext.onReady(function(){Ext.create("Ext.Viewport",{
id: "PageContent_Viewport1",
renderTo: Ext.getBody(),
items: [
{
id: "PageContent_Panel1",
itemId: "Panel1",
height: 150,
html: "North",
items: [
{
id: "PageContent_testButton",
itemId: "testButton",
xtype: "button",
handler: function(){App.PageContent_testButton.onButtonClic ked();},
text: "Test"
}
],
bodyPadding: 6,
title: "Some Panel"
}
],
layout: "fit"
});});
//]]>
</script>
</head>
<body>


<div>




<script>
Ext.onReady(function () {
debugger;
});

</script>


</div>



</body>
</html>


#{testButton} was translated to App.PageContent_testButton which is undefined, because the App.testButton was set instead. So it seems that setting the ItemID property affects how the references are set in the parent objects. I wonder if this is a bug. I think it is, because the procedure that replaces the #{..} doesn't take into account the scenario when ItemID was set (and the Namespace on control was not - found this later;). See the BaseControl.ClientID.

I still haven't figured out how Ext.Net/ExtJs chooses the parent object to set the references under. In my sample it is App (in ExtJs 3 it was window). I wonder which components act as container of this sort. Panel is an Ext.container.Container, however the reference was still set under App.

Another update:

Found this: http://forums.ext.net/showthread.php?10334-CLOSED-1-0-New-NameSpace-property

It seems that if I set the Namespace on the button then the code gets generated properly:

This:

<ext:Button runat="server" Text="Test" ID="testButton" Namespace="App" ItemID="testButton" Handler="#{testButton}.onButtonClicked();"></ext:Button>


will translate to this:

{
id: "PageContent_testButton",
itemId: "testButton",
xtype: "button",
handler: function(){App.testButton.onButtonClicked();},
text: "Test"
}

which is correct.


Thank you

Baidaly
Dec 07, 2012, 2:13 AM
Hello!

Thank you! We are investigating.

Daniil
Dec 07, 2012, 6:11 AM
Hello @bogc,

Thank you for the excellent investigation.

Regarding the App namespace. Please take a look at the breaking change item #90.


90. ResourceManager Namespace is "App" by default. Any widget will share own client id in that namespace.

Example (client side)

//Old

TextField1.setValue("Hello World!");

//New

App.TextField1.setValue("Hello World!");

or

//New

#{TextField1}.setValue("Hello World!");

You can set up an empty Namespace to get the same as it's in Ext.NET v1.

Example


<ext:ResourceManager runat="server" Namespace="" />


It is also possible to set up Namespace in the extnet section in Web.config.

Also you may be interested to investigate this thread.
http://forums.ext.net/showthread.php?18961

Daniil
Dec 07, 2012, 6:29 AM
Regarding your test case with ItemID. Seems #{} doesn't work well if ItemID is used.

Here is a simplified sample. We are investigating.

Example MasterPage

<%@ Master Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<ext:ResourceManager runat="server" />
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" />
</body>
</html>


Example Content Page

<%@ Page Language="C#" MasterPageFile="~/Page.Master" %>

<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<ext:XScript runat="server">
<script>
Ext.onReady(function () {
alert('#{testButton}' + " => " + #{testButton});
});
</script>
</ext:XScript>
<ext:Button runat="server" Text="Test" ID="testButton" ItemID="buttonItemID" />
</asp:Content>


Regarding ItemID in Ext.NET. Generally, it means the same in Ext.NET as it means in ExtJS.
http://docs.sencha.com/ext-js/4-1/#!/api/Ext.AbstractComponent-cfg-itemId

Daniil
Dec 07, 2012, 2:49 PM
Regarding your test case with ItemID. Seems #{} doesn't work well if ItemID is used.

Here is a simplified sample. We are investigating.

Example MasterPage

<%@ Master Language="C#" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<ext:ResourceManager runat="server" />
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" />
</body>
</html>


Example Content Page

<%@ Page Language="C#" MasterPageFile="~/Page.Master" %>

<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<ext:XScript runat="server">
<script>
Ext.onReady(function () {
alert('#{testButton}' + " => " + #{testButton});
});
</script>
</ext:XScript>
<ext:Button runat="server" Text="Test" ID="testButton" ItemID="buttonItemID" />
</asp:Content>



It has been fixed in SVN. Thank you again for the report.

By the way, do you really need ID and ItemID at the same time?

bogc
Dec 07, 2012, 4:44 PM
By the way, do you really need ID and ItemID at the same time?

I got into the habit of doing it (I set the ItemID to have access to the ExtJs objects through references), however, I will probably get rid of the ItemID.

Thank you the prompt response.

jchau
Dec 07, 2012, 5:11 PM
I got into the habit of doing it (I set the ItemID to have access to the ExtJs objects through references), however, I will probably get rid of the ItemID.

Thank you the prompt response.

itemId is useful because it doesn't have to be unique across the page but only unique to the parent component. We use it alot when creating reusable controls in javascript.

bogc
Dec 07, 2012, 6:07 PM
Do you know roughly when is this change going to make it to an official release?

Thanks

Daniil
Dec 10, 2012, 4:46 AM
I got into the habit of doing it (I set the ItemID to have access to the ExtJs objects through references), however, I will probably get rid of the ItemID.


Yes, as @jchau stated, ItemID can be very helpful to organize the things. Here is an example.
http://forums.ext.net/showthread.php?21393&p=92621&viewfull=1#post92621


Do you know roughly when is this change going to make it to an official release?

We depend on ExtJS here. Our 2.2 release should appear shortly after ExtJS 4.2 release. I have not seen yet any official time frames for 4.2.

So, I can't say anything concrete.