Sumário
Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)
Trabalhando com dados, Combobox e GridPanel
À essa altura do tópico, já temos conhecimento sobre os componentes, “DirectMethod“, “DirectEvents“, “Listeners“, entre outras coisas. Então é hora de entendermos como podemos exibir os dados aos nossos usuários. Neste tópico eu vou apresentar à vocês a classe “Store“. Então, vamos lá.
Store
O “Store” é um componente que trata os dados entre o cliente e o servidor, normalmente utilizado com componentes do tipo “Grids” e “Comboboxes“. Um “Store” tem a capacidade de filtrar e ordenar os dados, seja local ou remotamente.
Este por sua vez, tem dois pontos importantes:
- Um “Model“, onde definimos os tipos de dados, nomes de campos, validações, entre outros;
- Um “Proxy“, responsável pelas requisições entre cliente e servidor, e manter os dados atualizados no lado cliente;
Models
Um “Model” define os dados que o “Store” irá tratar. Em versões anteriores do Ext.NET, este era conhecido como “Record“. No “Model” podemos definir os dados, as validações, nomes para cada campo e formato.
Proxy
Um “Proxy” é utilizado para manter os dados, é uma abstração para o mecanismo de tratamento dos dados e se divide em dois tipos:
- Client-Side Proxies;
- MemoryProxy: É um simples “proxy” que mantem os dados na memória do navegador;
- LocalStorageProxy e SessionStorageProxy: Usam a nova definição de armazenamento do HTML5. Não funcionam em navegadores mais antigos, pois estes não aceitam HTML5
-
(Eu ainda não estou muito familiarizado com o HTML5 e as novas definições de proxy para o mesmo. Para evitar informação errada, vou parar por aqui 🙂 )
- Server-Side Proxies;
- AjaxProxy: Este é um “proxy” de propósito geral, que aceita objetos do tipo array, cada índice é um nome de coluna definido no “model“;
- JsonPProxy: Permite requisições AJAX “cross-domain“;
- PageProxy: É um “proxy” que trabalha na página e permite a ligação com eventos no lado servidor;
Entendido o processo de acesso utilizando “Stores”, vamos botar em prática o que aprendemos.
Não se preocupe com os detalhes do código, vamos nos ater apenas ao uso do “Store” e suas peculiaridades.
Antes de começar
Para os dois exemplos, temos que preparar o nosso ambiente antes de começar, para isso, crie dois arquivos de estilo.
combobox.css
.list-item { font: normal 11px tahoma, arial, helvetica, sans-serif; padding: 3px 10px 3px 10px; border: 1px solid #fff; border-bottom: 1px solid #eeeeee; white-space: normal; color: #555; } .list-item h3 { display: block; font: inherit; font-weight: bold; margin: 0px; color: #222; }
gridpanel.css
.x-grid-cell-fullName .x-grid-cell-inner { font-family: tahoma, verdana; display: block; font-weight: normal; font-style: normal; color: #385F95; white-space: normal; } .x-grid-rowbody div { margin: 2px 5px 20px 5px !important; width: 99%; color: Blue; } .x-grid-row-expanded td.x-grid-cell { border-bottom-width: 0px; }
Estes dois arquivos serão responsáveis pela apresentação dos dados no lado cliente.
Continuando …
Exibindo os dados…
Vamos utilizar uma lista de objetos para exibir e tratar os dados do lado cliente. Nos dois exemplos iremos configurar um “Store” para uma “Combbox” e para uma “GridPanel“.
Veja os exemplos:
Atente apenas ao uso do “Store”. O Resto do código será explicado posteriormente.
GridPanel
ASPX Code
<head id="Head1" runat="server"> <title>Tutorial Ext.NET</title> <link href="../css/gridpanel.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="../Scripts/GridPanel.js"></script> </head> <body> <form id="Form1" runat="server"> <ext:ResourceManager ID="ResourceManager1" runat="server" /> <ext:Window ID="Window1" runat="server" Collapsible="true" Maximizable="true" Icon="Money" Title="Orders List" Width="1300" Height="600" X="50" Y="50" Layout="Fit" Closable="false"> <Items> <ext:GridPanel ID="GridPanel1" runat="server" Title="Employees" Frame="true" Header="false" Border="false"> <Store> <ext:Store ID="Store1" runat="server" OnReadData="Store1_ReadData"> <Model> <ext:Model ID="Model1" runat="server"> <Fields> <ext:ModelField Name="CustomerID" /> <ext:ModelField Name="EmployeeID" /> <ext:ModelField Name="OrderDate" /> <ext:ModelField Name="RequiredDate" /> <ext:ModelField Name="ShippedDate" /> <ext:ModelField Name="ShipVia" /> <ext:ModelField Name="Freight" /> <ext:ModelField Name="ShipName" /> <ext:ModelField Name="ShipAddress" /> <ext:ModelField Name="ShipCity" /> <ext:ModelField Name="ShipRegion" /> <ext:ModelField Name="ShipPostalCode" /> <ext:ModelField Name="ShipCountry" /> </Fields> </ext:Model> </Model> </ext:Store> </Store> <ColumnModel ID="ColumnModel1" runat="server"> <Columns> <ext:Column ID="Column0" runat="server" Text="CustomerID" Width="150" DataIndex="CustomerID"> </ext:Column> <ext:Column ID="Column1" runat="server" DataIndex="EmployeeID" Text="EmployeeID" Width="150" /> <ext:DateColumn ID="Column2" runat="server" DataIndex="OrderDate" Text="Order Date" Width="150" Format="dd/MM/yyyy" /> <ext:DateColumn ID="DateColumn1" runat="server" DataIndex="RequiredDate" Text="Required Date" Width="110" Format="dd/MM/yyyy" /> <ext:DateColumn ID="DateColumn2" runat="server" DataIndex="ShippedDate" Text="Shipped Date" Width="110" Format="dd/MM/yyyy" /> <ext:Column ID="Column3" runat="server" DataIndex="ShipVia" Text="Ship Via" Width="150" /> <ext:Column ID="Column4" runat="server" DataIndex="Freight" Text="Freight" Width="100" /> </Columns> </ColumnModel> <View> <ext:GridView ID="GridView1" runat="server"> <GetRowClass Handler="return 'x-grid-row-expanded';" /> </ext:GridView> </View> <SelectionModel> <ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" /> </SelectionModel> <Features> <ext:RowBody ID="RowBody1" runat="server"> <GetAdditionalData Handler="orig.rowBody = '<div><span style=\'color: red\'>Ship Information</span>' + '</br/>' + data.ShipName + '</br/>' + data.ShipAddress + '</br/>' + data.ShipCity + (data.ShipRegion == null ? '' : ' - ' + data.ShipRegion) + '</br/>' + (data.ShipPostalCode == null ? '' : data.ShipPostalCode + '</br/>') + data.ShipCountry + '</div>'; orig.rowBodyColspan = record.fields.getCount();" /> </ext:RowBody> </Features> <BottomBar> <ext:PagingToolbar ID="PagingToolbar1" runat="server"> <Items> <ext:Label ID="Label1" runat="server" Text="Page size:" /> <ext:ToolbarSpacer ID="ToolbarSpacer1" runat="server" Width="10" /> <ext:ComboBox ID="ComboBox1" runat="server" Width="80"> <Items> <ext:ListItem Text="1" /> <ext:ListItem Text="2" /> <ext:ListItem Text="10" /> <ext:ListItem Text="20" /> </Items> <SelectedItems> <ext:ListItem Value="10" /> </SelectedItems> <Listeners> <Select Handler="#{GridPanel1}.store.pageSize = parseInt(this.getValue(), 10); #{GridPanel1}.store.reload();" /> </Listeners> </ext:ComboBox> </Items> <Plugins> <ext:ProgressBarPager ID="ProgressBarPager1" runat="server" /> </Plugins> </ext:PagingToolbar> </BottomBar> </ext:GridPanel> </Items> </ext:Window> </form> </body>
Code Behind
public partial class GridPanelArray: System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if(!X.IsAjaxRequest) { this.BindData(); } } protected void Store1_ReadData(object sender, StoreReadDataEventArgs e) { BindData(); } private void BindData() { Store store = this.GridPanel1.GetStore(); store.DataSource = this.Data; store.DataBind(); } List<Order> Data { get { return Order.Find<Order>(); } } }
No código acima, temos o método que será chamado quando o “Store” requisitar os dados para o servidor, “Store1_ReadData“. Este método por sua vez chama o método “BindData()“, dentro do método “BindData()”, é carregado uma lista de pedidos (“Order”) e retornados para a propriedade “DataSource” do “Store“, e logo em seguida fazemos a ligação dos dados chamando o método “Store.DataBind()“.
ComboBox
<ext:ComboBox ID="ComboBox4" runat="server" FieldLabel="Selecione vários colaboradores" DisplayField="FirstName" Width="320" LabelWidth="130" QueryMode="Local" TypeAhead="true" MultiSelect="true"> <Store> <ext:Store ID="Store4" runat="server" Data="<%# ArrayOfEmployees %>" AutoDataBind="true"> <Model> <ext:Model ID="Model4" runat="server"> <Fields> <ext:ModelField Name="EmployeeID" /> <ext:ModelField Name="FirstName" /> <ext:ModelField Name="LastName" /> </Fields> </ext:Model> </Model> <Reader> <ext:ArrayReader /> </Reader> </ext:Store> </Store> <ListConfig> <ItemTpl ID="ItemTpl1" runat="server"> <Html> <div class="list-item"> <h3>ID: {EmployeeID}</h3> {FirstName} {LastName} </div> </Html> </ItemTpl> </ListConfig> </ext:ComboBox>
Code Behind
public object ArrayOfEmployees { get { object result = (from e in Employee.Find<Employee>() select new object[] { e.EmployeeID, e.FirstName, e.LastName, }).ToArray(); return result; } }
No exemplo do combobox não mudou muita coisa, definimos um “Model” com o mapeamento dos campos, mas … Temos uma diferença, definimos que o nosso “Reader” irá utilizar uma “ArrayReader”, logo temos que retornar um “Array” de objetos, isto ficou a cargo da propriedade “ArrayOfEmployees“. A chamada também foi modificada, não usamos o evento “OnDataRead“, e sim a propriedade “Data” com um diretiva ASPX <%# ArrayOfEmployees %>, em ASPX esta diretiva diz ao interpretador para retornar um objeto “datasource“.
Utilizando um DataSource.
O Ext.NET aceita diversos tipos de “DataSources”:
- LinqDataSource: Aceita comando do tipo “LINQ”;
- ObjectDataSource: Aceita classes definidas dentro da nossa aplicação. Eu gosto deste 🙂
- SqlDataSource: Aceita comando do tipo SQL;
- XmlDataSource: Aceita arquivos do tipo XML. Este datasource requer que seja criado um “Transform” para que possa compreender os dados;
![]() |
Você pode usar diversos “datasources” em uma mesma página, para isso basta definir o ID de cada um, e ao utilizar em um “Store“, define o ID do “datasource” na propriedade “Store.DataSourceID“. Cada Store só pode ter um “datasource” definido. Para saber mais: http://examples.ext.net/#/search/datasource |
No exemplo abaixo iremos ver o “ObjectDataSource” em ação.
ASPX Code
<body> <form id="Form1" runat="server"> <ext:ResourceManager ID="ResourceManager1" runat="server" /> <asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="Find" TypeName="Ext.Net.Tutorial.Data.Order" /> <ext:Window ID="Window1" runat="server" Collapsible="true" Maximizable="true" Icon="Money" Title="Orders List" Width="1300" Height="600" X="50" Y="50" Layout="Fit" Closable="false"> <Items> <ext:GridPanel ID="GridPanel1" runat="server" Title="Employees" Frame="true" Header="false" Border="false"> <Store> <ext:Store ID="Store1" runat="server" DataSourceID="ObjectDataSource1"> <Model> <ext:Model ID="Model1" runat="server"> <Fields> <ext:ModelField Name="CustomerID" /> <ext:ModelField Name="EmployeeID" /> <ext:ModelField Name="OrderDate" /> <ext:ModelField Name="RequiredDate" /> <ext:ModelField Name="ShippedDate" /> <ext:ModelField Name="ShipVia" /> <ext:ModelField Name="Freight" /> <ext:ModelField Name="ShipName" /> <ext:ModelField Name="ShipAddress" /> <ext:ModelField Name="ShipCity" /> <ext:ModelField Name="ShipRegion" /> <ext:ModelField Name="ShipPostalCode" /> <ext:ModelField Name="ShipCountry" /> </Fields> </ext:Model> </Model> </ext:Store> </Store> <ColumnModel ID="ColumnModel1" runat="server"> <Columns> <ext:Column ID="Column0" runat="server" Text="CustomerID" Width="150" DataIndex="CustomerID"> </ext:Column> <ext:Column ID="Column1" runat="server" DataIndex="EmployeeID" Text="EmployeeID" Width="150" /> <ext:DateColumn ID="Column2" runat="server" DataIndex="OrderDate" Text="Order Date" Width="150" Format="dd/MM/yyyy" /> <ext:DateColumn ID="DateColumn1" runat="server" DataIndex="RequiredDate" Text="Required Date" Width="110" Format="dd/MM/yyyy" /> <ext:DateColumn ID="DateColumn2" runat="server" DataIndex="ShippedDate" Text="Shipped Date" Width="110" Format="dd/MM/yyyy" /> <ext:Column ID="Column3" runat="server" DataIndex="ShipVia" Text="Ship Via" Width="150" /> <ext:Column ID="Column4" runat="server" DataIndex="Freight" Text="Freight" Width="100" /> </Columns> </ColumnModel> <View> <ext:GridView ID="GridView1" runat="server"> <GetRowClass Handler="return 'x-grid-row-expanded';" /> </ext:GridView> </View> <SelectionModel> <ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" /> </SelectionModel> <Features> <ext:RowBody ID="RowBody1" runat="server"> <GetAdditionalData Handler="orig.rowBody = '<div><span style=\'color: red\'>Ship Information</span>' + '</br/>' + data.ShipName + '</br/>' + data.ShipAddress + '</br/>' + data.ShipCity + (data.ShipRegion == null ? '' : ' - ' + data.ShipRegion) + '</br/>' + (data.ShipPostalCode == null ? '' : data.ShipPostalCode + '</br/>') + data.ShipCountry + '</div>'; orig.rowBodyColspan = record.fields.getCount();" /> </ext:RowBody> </Features> </ext:GridPanel> </Items> </ext:Window> </form> </body>
No código em destaque, acima, definimos o “ObjectDataSource” para o nosso “Store“, vamos explicar algumas propriedades:
- ID: “ObjectDataSource1”: Define o nome do objeto “DataSource” que deverá ser utilizado no “Store“;
- TypeName: “Ext.Net.Tutorial.Data.Order”: Define o nome do objeto que será instanciado pelo “DataSource”;
- SelectMethod: “Find”: Nome do método que será chamado para popular o “DataSource”;
Nas outras linhas em destaque, como sempre, definimos o nosso “Model” e já estamos familiarizados com ele.
Utilizando um Proxy
Até que enfim… Falamos tanto do acesso aos dados, de diversas formas, que já estava esquecendo deste tal “proxy“. Vamos ver como trabalhar com o proxy. Para isso, iremos criar um “ASPX Hanlder“.
Preparando o ambiente.
Antes de começarmos, iremos criar 3 “ASPX Handlers”:
- HandlerBase<T>: Abstração para o tratamento dos dados, pois o código de tratamento é semelhante para todos os outros “handlers” que tratam o acesso aos dados.
- EmployeeHandler: É o “handler” responsável por exibir os dados dos colaboradores;
- OrderHandler: É o “handler” responsável por exibir os dados dos pedidos;
Abstração HandlerBase
public abstract class HandlerBase<T>: System.Web.IHttpHandler where T: IModelBase, new() { public void ProcessRequest(HttpContext context) { //------------------------------------------------------------------------- // Definir o tipo de retorno da resposta da requisição. // Iremos retornar um objeto do tipo JSON //------------------------------------------------------------------------- context.Response.ContentType = "application/json"; //------------------------------------------------------------------------- // Recuperar os parâmetros que foram passados pela requisição //------------------------------------------------------------------------- StoreRequestParameters storeParams = new StoreRequestParameters(context); //------------------------------------------------------------------------- // Paginar //------------------------------------------------------------------------- Paging<T> data = DataPaging(storeParams.Start, storeParams.Limit, storeParams.Sort.Count() > 0 ? storeParams.Sort[0].Property : "", storeParams.Sort.Count() > 0 ? storeParams.Sort[0].Direction.ToString() : "", storeParams.GridFilters); context.Response.Write(JSON.Serialize(data)); } public bool IsReusable { get { return false; } } public static Paging<T> DataPaging(int start, int limit, string sort, string dir, FilterConditions fc) { List<T> data = DbContext.Find<T>(new T()); #region Filtrar //------------------------------------------------------------------------- // Se foi definido alguma condição, temos que filtrar os registros //------------------------------------------------------------------------- if(fc != null && fc.Conditions.Count > 0) { foreach(FilterCondition condition in fc.Conditions) { Comparison comparison = condition.Comparison; string field = condition.Field; FilterType type = condition.Type; object value; switch(condition.Type) { case FilterType.Boolean: value = condition.Value<bool>(); break; case FilterType.Date: value = condition.Value<DateTime>(); break; case FilterType.List: value = condition.List; break; case FilterType.Numeric: if(data.Count > 0 && data[0].GetType().GetProperty(field).PropertyType == typeof(int)) { value = condition.Value<int>(); } else { value = condition.Value<double>(); } break; case FilterType.String: value = condition.Value<string>(); break; default: throw new ArgumentOutOfRangeException(); } //------------------------------------------------------------------------- // Aqui removemos todos os registros que não satisfazem a condição //------------------------------------------------------------------------- data.RemoveAll( item => { object oValue = item.GetType().GetProperty(field).GetValue(item, null); IComparable cItem = oValue as IComparable; switch(comparison) { case Comparison.Eq: switch(type) { case FilterType.List: return !(value as List<string>).Contains(oValue.ToString()); case FilterType.String: return !oValue.ToString().ToLower().Contains(value.ToString().ToLower()); default: return !cItem.Equals(value); } case Comparison.Gt: return cItem.CompareTo(value) < 1; case Comparison.Lt: return cItem.CompareTo(value) > -1; default: throw new ArgumentOutOfRangeException(); } } ); } } #endregion #region Ordenar //------------------------------------------------------------------------- // Ordena os registros de acordo com o que foi passado pelo usuário //------------------------------------------------------------------------- if(!string.IsNullOrEmpty(sort)) { data.Sort(delegate(T x, T y) { object a; object b; int direction = dir == "DESC" ? -1 : 1; a = x.GetType().GetProperty(sort).GetValue(x, null); b = y.GetType().GetProperty(sort).GetValue(y, null); return CaseInsensitiveComparer.Default.Compare(a, b) * direction; }); } #endregion #region Paginar //------------------------------------------------------------------------- // Faz a paginação do registro. //------------------------------------------------------------------------- if((start + limit) > data.Count) { limit = data.Count - start; } List<T> rangeData = (start < 0 || limit < 0) ? data : data.GetRange(start, limit); #endregion //retornar return new Paging<T>(rangeData, data.Count); } }
Exemplos de acesso
Classe concreta EmployeeHandler
/// <summary> /// Summary description for EmployeeHandler /// </summary> public class EmployeeHandler: HandlerBase<Employee> { }
Classe concreta OrderHandler
/// <summary> /// Summary description for GridPanelHandler /// </summary> public class OrderHandler: HandlerBase<Order> { }
Estamos quase lá… Vamos ver agora dois exemplos, uma “Combobox” e uma “GridPanel” acessando os dados por um “proxy” e utilizando um “handler” para tratar os dados.
ASPX Code
<ext:ComboBox ID="ComboBox5" runat="server" FieldLabel="Selecione vários colaboradores" DisplayField="FirstName" Width="320" LabelWidth="130" QueryMode="Local" TypeAhead="true" MultiSelect="true"> <Store> <ext:Store ID="Store5" runat="server" AutoDataBind="true"> <Proxy> <ext:AjaxProxy Url="../DataHandler/EmployeeHandler.ashx"> <ActionMethods Read="GET" /> <Reader> <ext:JsonReader Root="data" TotalProperty="total" /> </Reader> </ext:AjaxProxy> </Proxy> <Model> <ext:Model ID="Model5" runat="server"> <Fields> <ext:ModelField Name="EmployeeID" /> <ext:ModelField Name="FirstName" /> <ext:ModelField Name="LastName" /> </Fields> </ext:Model> </Model> </ext:Store> </Store> <ListConfig> <ItemTpl ID="ItemTpl2" runat="server"> <Html> <div class="list-item"> <h3>ID: {EmployeeID}</h3> {FirstName} {LastName} </div> </Html> </ItemTpl> </ListConfig> </ext:ComboBox>
GridPanel
ASPX Code
<head id="Head1" runat="server"> <title>Tutorial Ext.NET</title> <link href="../css/gridpanel.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="../Scripts/GridPanel.js"></script> </head> <body> <form id="Form1" runat="server"> <ext:ResourceManager ID="ResourceManager1" runat="server" /> <ext:Window ID="Window1" runat="server" Collapsible="true" Maximizable="true" Icon="Money" Title="Orders List" Width="1300" Height="600" X="50" Y="50" Layout="Fit" Closable="false"> <Items> <ext:GridPanel ID="GridPanel1" runat="server" Title="Employees" Frame="true" Header="false" Border="false"> <Store> <ext:Store ID="Store1" runat="server" PageSize="10"> <Proxy> <ext:AjaxProxy Url="../DataHandler/OrderHandler.ashx"> <ActionMethods Read="GET" /> <Reader> <ext:JsonReader Root="data" TotalProperty="total" /> </Reader> </ext:AjaxProxy> </Proxy> <Model> <ext:Model ID="Model1" runat="server"> <Fields> <ext:ModelField Name="CustomerID" /> <ext:ModelField Name="EmployeeID" /> <ext:ModelField Name="OrderDate" /> <ext:ModelField Name="RequiredDate" /> <ext:ModelField Name="ShippedDate" /> <ext:ModelField Name="ShipVia" /> <ext:ModelField Name="Freight" /> <ext:ModelField Name="ShipName" /> <ext:ModelField Name="ShipAddress" /> <ext:ModelField Name="ShipCity" /> <ext:ModelField Name="ShipRegion" /> <ext:ModelField Name="ShipPostalCode" /> <ext:ModelField Name="ShipCountry" /> </Fields> </ext:Model> </Model> <Sorters> <ext:DataSorter Property="CustomerID" Direction="ASC" /> </Sorters> </ext:Store> </Store> <ColumnModel ID="ColumnModel1" runat="server"> <Columns> <ext:Column ID="Column0" runat="server" Text="CustomerID" Width="150" DataIndex="CustomerID"> </ext:Column> <ext:Column ID="Column1" runat="server" DataIndex="EmployeeID" Text="EmployeeID" Width="150" /> <ext:DateColumn ID="Column2" runat="server" DataIndex="OrderDate" Text="Order Date" Width="150" Format="dd/MM/yyyy" /> <ext:DateColumn ID="DateColumn1" runat="server" DataIndex="RequiredDate" Text="Required Date" Width="110" Format="dd/MM/yyyy" /> <ext:DateColumn ID="DateColumn2" runat="server" DataIndex="ShippedDate" Text="Shipped Date" Width="110" Format="dd/MM/yyyy" /> <ext:Column ID="Column3" runat="server" DataIndex="ShipVia" Text="Ship Via" Width="150" /> <ext:Column ID="Column4" runat="server" DataIndex="Freight" Text="Freight" Width="100" /> </Columns> </ColumnModel> <View> <ext:GridView ID="GridView1" runat="server"> <GetRowClass Handler="return 'x-grid-row-expanded';" /> </ext:GridView> </View> <SelectionModel> <ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" /> </SelectionModel> <Features> <ext:RowBody ID="RowBody1" runat="server"> <GetAdditionalData Handler="orig.rowBody = '<div><span style=\'color: red\'>Ship Information</span>' + '</br/>' + data.ShipName + '</br/>' + data.ShipAddress + '</br/>' + data.ShipCity + (data.ShipRegion == null ? '' : ' - ' + data.ShipRegion) + '</br/>' + (data.ShipPostalCode == null ? '' : data.ShipPostalCode + '</br/>') + data.ShipCountry + '</div>'; orig.rowBodyColspan = record.fields.getCount();" /> </ext:RowBody> </Features> <BottomBar> <ext:PagingToolbar ID="PagingToolbar1" runat="server"> <Items> <ext:Label ID="Label1" runat="server" Text="Page size:" /> <ext:ToolbarSpacer ID="ToolbarSpacer1" runat="server" Width="10" /> <ext:ComboBox ID="ComboBox1" runat="server" Width="80"> <Items> <ext:ListItem Text="1" /> <ext:ListItem Text="2" /> <ext:ListItem Text="10" /> <ext:ListItem Text="20" /> <ext:ListItem Text="40" /> <ext:ListItem Text="100" /> </Items> <SelectedItems> <ext:ListItem Value="10" /> </SelectedItems> <Listeners> <Select Handler="#{GridPanel1}.store.pageSize = parseInt(this.getValue(), 10); #{GridPanel1}.store.reload();" /> </Listeners> </ext:ComboBox> </Items> <Plugins> <ext:ProgressBarPager ID="ProgressBarPager1" runat="server" /> </Plugins> </ext:PagingToolbar> </BottomBar> <Features> <ext:GridFilters ID="GridFilters1" runat="server"> <Filters> <ext:StringFilter DataIndex="CustomerID" /> <ext:NumericFilter DataIndex="EmployeeID" /> <ext:DateFilter DataIndex="OrderDate"> <DatePickerOptions runat="server" TodayText="Now" /> </ext:DateFilter> <ext:DateFilter DataIndex="RequiredDate"> <DatePickerOptions runat="server" TodayText="Now" /> </ext:DateFilter> <ext:DateFilter DataIndex="ShippedDate"> <DatePickerOptions runat="server" TodayText="Now" /> </ext:DateFilter> <ext:NumericFilter DataIndex="ShipVia" /> <ext:NumericFilter DataIndex="Freight" /> </Filters> </ext:GridFilters> </Features> </ext:GridPanel> </Items> </ext:Window> </form> </body> </html>
Vejam nos códigos em destaque a definição do proxy, vamos agora explicar o que é cada propriedade que foi utilizada.
- “<Proxy>“: Usamos esta marcação para definir que neste “Store” será usado um “proxy“.
- “<ext:AjaxProxy Url=”../DataHandler/OrderHandler.ashx”>“: Esta marcação define o tipo de “proxy” que iremos usar. Eu utilizo, na maioria das vezes, o “AjaxProxy“, sempre me atendeu. Na definição desta marcação temos a propriedade “Url” e como podem ver, ela define o caminho do nosso “handler” em relação à página;
- “<ActionMethods Read=”GET” />“: Aqui definimos a ação da requisição como um “GET“, pois vamos solicitar uma informação;
- “<ext:JsonReader Root=”data” TotalProperty=”total” />“: Nesta marcação, definimos o nosso “Reader“, nosso leitor da informação, como eu defini que meu retorno no “handler” será um “JSON” .
-
Lembram da definição do “handler“? context.Response.ContentType = “application/json“;
- Esta marcação tem duas propriedades importantes:
- “Root“, que define o nome da marcação pai de todas, no objeto “JSON” retornado e;
- “TotalProperty“, que define o nome da propriedade que representa o total de registros retornados pela aplicação. Veja abaixo um retorno para facilitar o entendimento destas duas propriedades
{ "data": [{ "ID": 1, "EmployeeID": 1, "LastName": "Davolio", "FirstName": "Nancy", "Title": "Sales Representative", "TitleOfCourtesy": "Ms.", "BirthDate": "1948-12-08T00:00:00", "HireDate": "1992-05-01T00:00:00", "Address": "507 - 20th Ave. E.Apt. 2A", "City": "Seattle", "Region": "WA", "PostalCode": "98122", "Country": "USA", "HomePhone": "(206) 555-9857", "Extension": "5467", "Photo": "System.Byte[]", "Notes": "Education includes a BA in psychology from Colorado State University in 1970. She also completed \"The Art of the Cold Call.\" Nancy is a member of Toastmasters International.", "ReportsTo": 2, "PhotoPath": "http://accweb/emmployees/davolio.bmp", "New": false }], "total": 1 }
-
É isso ai pessoal 🙂
Até o próximo
♦ Marcelo