Sumário
Para um melhor entendimento deste Artigo veja o Índice (Rich Internet Applications com Ext.Net)
Criando componentes no lado Servidor
Ao desenvolvermos um componente utilizando como base um componente já criado no Ext.NET, ganhamos de brinde toda a reutilização deste, por exemplo: – Nosso componente já pode ser utilizado em WebForm, em ASP MVC, com a engine Razor, no código markup, etc.
Outra vantagem desta abordagem é que quando estudamos o código do Ext.NET, você poderá entender como eles criam seus componentes com base nos componentes Ext JS,e não necessariamente você precisa ser um conhecedor profundo do Ext JS.
Como vantagem também, podemos citar que você pode desenvolver seu componente em qualquer linguagem .NET que você tenha familiaridade e não precisa aprender a ser um ninja em javascript, pois todo o javascript será gerado para o lado cliente.
Neste tópico, iremos focar na criação do componente do lado servidor, na utilização do lado cliente, e como criar seus próprios métodos que podem ser acessados do lado cliente e lado servidor.
Antes de começarmos…
Vamos definir nossas abstrações e nossos objetos de validação do componente. Como neste artigo eu irei criar dois componentes para inserção de texto. Iremos criar uma abstração para tipos texto e uma classe de resultado da validação.
Classe ValidateResult
/// <summary> /// Classe que determina o resultado da validação feita e retorna. /// </summary> public sealed class ValidateResult { #region locais bool valid = true; string invalidMessage = ""; #endregion #region propriedades /// <summary> /// Se true, o valor inserido no componente é valido. /// </summary> public bool Valid { get { return valid; } private set { valid = value; } } /// <summary> /// Se não for válido é necessário informar uma mensagem de erro /// </summary> public string InvalidMessage { get { return invalidMessage; } private set { invalidMessage = value; } } #endregion #region Construtores /// <summary> /// Inicia o resultado da validação /// </summary> /// <param name="valid">true/false para válido ou não.</param> /// <param name="invalidMessage">Se "valid" for verdadeiro, é obrigatório informar a mensagem.</param> /// <exception cref="ArgumentException">Se "valid" for verdadeiro, e o parâmetro "invalidMessage" /// não for informado. Esta exceção será lançada.</exception> public ValidateResult(bool valid, string invalidMessage = "") { this.valid = valid; if(!valid && String.IsNullOrEmpty(invalidMessage)) throw new ArgumentException("Se \"valid\" for definido como false. É obrigatório informar uma mensagem de erro em \"invalidMessage\".", "invalidMessage"); this.invalidMessage = invalidMessage; } #endregion }
Abstração para campos do tipo texto (TextFieldBase)
public abstract class TextFieldBase: Ext.Net.TextField, IValidator { public TextFieldBase() : base() { } #region IValidator Members public string ErrorMessage { get; set; } public bool IsValid { get; set; } public override void Validate() { ValidateResult result = Validate(Text); IsValid = result.Valid; ErrorMessage = result.InvalidMessage; if(IsValid) MarkAsValid(); else MarkInvalid(ErrorMessage); } /// <summary> /// Faz a validação do componente e retorna true se o texto do componente for válido, caso contrário false /// </summary> /// <param name="value">valor que deverá ser validado</param> /// <returns></returns> protected abstract ValidateResult Validate(string value); #endregion }
Ok! Definimos a nossa abstração. Vamos agora criar o nosso componente.
Meu primeiro componente
Vamos criar um componente bem simples. Um campo de CEP, que irá fazer uma validação e será utilizado em uma página.
CEPField
public class CEPField: TextFieldBase { #region Contrutores public CEPField() : base() { DirectEvents.Blur.Event += new ComponentDirectEvent.DirectEventHandler(Blur_Event); AllowBlank = false; this.IsRemoteValidation = true; this.RemoteValidation.Validation += new RemoteValidationDirectEvent.RemoteValidationEventHandler(RemoteValidation_Validation); FieldLabel = "CEP"; } #endregion #region Tratadores de eventos void RemoteValidation_Validation(object sender, RemoteValidationEventArgs e) { Validate(); e.Success = IsValid; e.ErrorMessage = ErrorMessage; } void Blur_Event(object sender, DirectEventArgs e) { this.SetValue(Format.CEP(Text)); } #endregion #region overrides public override void SetValue(object value) { Validate(); base.SetValue(value); if(!string.IsNullOrEmpty(ClientID)) Ext.Net.X.AddScript(ClientID + ".isValid = function(){return " + IsValid.ToString().ToLower() + ";};"); } public override int MaxLength { get { return 9; } set { base.MaxLength = 9; } } #endregion #region IValidator Members protected override ValidateResult Validate(string value) { if(AllowBlank && String.IsNullOrEmpty(value)) return new ValidateResult(true); value = Utilities.OnlyNumbers(value); if(String.IsNullOrEmpty(value)) return new ValidateResult(false, "O CEP não pode ser vazio ou não foi digitado corretamente."); //permite somente números if(value.Count(w => !Char.IsNumber(w)) > 0) return new ValidateResult(false, "O CEP não é válido."); //para ser válido tem que ter 8 caracteres if(value.Length != 8) return new ValidateResult(false, "O CEP não é válido."); return new ValidateResult(true); } #endregion }
![]() |
Hm! OK! Eu criei meu componente. Mas como eu faço para chamá-lo em uma página asp? É possível utilizar a mesma marcação que temos para o Ext.NET, utilizando a tag “<ext>“? |
R: Sim, é possível, com um pequeno ajuste no nosso arquivo “web.config”.
Dentro da tag “” devemos inserir a linha em destaque, logo abaixo
<pages> <controls> <!--Indica que toda página criada irá ter a diretiva "ext" como padrão para ser usada como marcação na criação.--> <add assembly="Ext.Net" namespace="Ext.Net" tagPrefix="ext"/> <add assembly="Ext.Net.Tutorial" namespace="Ext.Net.Tutorial.ComponentModel" tagPrefix="tut"/> </controls> </pages>
- Esta linha indica que um assembly deverá ser adicionado; “add assembly“; para todas as páginas criadas;
- Os controles que estão no “namespace” …
- Deverão ser associados com o prefixo;”tagPrefix“; “tut“;
Pronto. Agora podemos utilizar o nosso componente apenas escrevendo a tag
<tut:CEPField ID="CEPField1" runat="server" FieldLabel="Informe seu CEP"> </tut:CEPField>
O próximo componente que será criado é um “CurrencyField“, um campo para inserir valores monetários. Vamos ver o código do mesmo, e explicar logo em seguida.
public class CurrencyField: TextFieldBase { #region Construtores public CurrencyField() : base() { //------------------------------------------------------------------------- // Define que só podemos digitar números de 0-9 e a vírgula. //------------------------------------------------------------------------- MaskRe = "/[0-9\\,]/"; //------------------------------------------------------------------------- // Define o método javascript que irá ser chamado ao receber o foco //------------------------------------------------------------------------- Listeners.Focus.Handler = "this.setRawValue(this.getNumber());this.selectText();"; //------------------------------------------------------------------------- // Define o método que será chamado ao perder o foco //------------------------------------------------------------------------- Listeners.Blur.Handler = "this.setValue(this._getValue(this.getValue()));"; //------------------------------------------------------------------------- // Define que o valor deverá ser alinhado a direta do componente //------------------------------------------------------------------------- FieldStyle = "text-align:right;"; } #endregion #region Overrides public override ConfigItemCollection CustomConfig { get { ConfigItemCollection result = base.CustomConfig; string curSbl = "R$"; #region _getValue //------------------------------------------------------------------------- // Criando o método _getValue para o lado cliente. //------------------------------------------------------------------------- ConfigItem it = new ConfigItem("_getValue", @"function(v){ return MyApp.Util.Format.currency(this.cleanValue(v), 2,'" + curSbl + @"'); } "); result.Add(it); #endregion #region getNumber //------------------------------------------------------------------------- // Criando o método getNumber para o lado cliente. //------------------------------------------------------------------------- it = new ConfigItem("getNumber", @"function(){ if(this.number === undefined || this.number == 0) this.number = MyApp.Convert.toNumber(this.getValue()); return this.number; } "); result.Add(it); #endregion #region setValue //------------------------------------------------------------------------- // Substituindo o método setValue, com a nossa definição //------------------------------------------------------------------------- it = new ConfigItem("setValue", @"function(v){ v = this._getValue(v); this.setRawValue(v); this.number = MyApp.Convert.toNumber(this.getValue()); this.text = v; } "); result.Add(it); #endregion #region cleanValue //------------------------------------------------------------------------- // Criando o método cleanValue para o lado cliente. //------------------------------------------------------------------------- it = new ConfigItem("cleanValue", @"function(v){ if(v){ return MyApp.Util.Format.number(v, 2); }else return 0; } "); result.Add(it); #endregion return result; } } public override void SetValue(object value) { this.SetValue(value.ToString()); base.SetValue(Number); } protected void SetValue(string text) { Text = text; Number = Convert.ToDouble(text); } #endregion #region Propriedades public virtual double Number { get { return Utilities.Convert.ToDouble(base.Text); } set { base.Text = value.ToString(); } } #endregion #region IValidator members protected override ValidateResult Validate(string value) { double d = Utilities.Convert.ToDouble(value); if(!AllowBlank && d == 0) return new ValidateResult(false, "É obrigatório informar o valor monetário."); return new ValidateResult(true); } #endregion }
Neste código foi apresentado um meio de você criar seus próprios métodos javascript e associá-los ao seus componentes.
Para isto, utilizamos o que chamamos de “CustomConfig“, veja nas linhas em destaque.
![]() |
O objeto “Ext.Net.ConfigItem“, permite que você defina métodos e propriedades para seus controles. Feito isso, você pode acessar em um código javascript.
var v = App.MyComponent._getValue(); |
Entendendo o objeto “Ext.Net.ConfigItem“
Este objeto tem a finalidade de vincular seus métodos javascript aos componentes Ext.NET, isso se torna útil quando estamos criando nossos próprios componentes.
Possui 3 propriedades importantes:
- Name: Define o nome do método ou propriedade que será exposto;
- Value: Define o valor que será representado pelo sue método ou propriedade;
- Mode: O mode pode ser:
- Auto: O Ext.NET tentará detectar o tipo e se não for capaz, A propriedade “Value” será encapsulada como uma string, ou como um número, de acordo com seu tipo;
- Raw: A propriedade “Value” será exposta como está;
- Value: Valor da propriedade ou código do método;
É isso ai pessoal 🙂
Até o próximo
♦ Marcelo