Criando Componentes Não Visual de Cliente personalizados

Este tópico mostra como criar um componente de cliente não visual AJAX no ASP.NET que deriva da classe base Sys.Component do cliente e como usar o componente em uma página.

Neste tutorial, você aprenderá como fazer o seguinte:

  • Use o padrão de design de protótipo para definir uma classe componente não visual em ECMAScript (JavaScript).

  • Registre um componente não visual como uma classe derivada da classe base Component.

  • Inicializar a classe base Component do componente não visual e chamar seus métodos.

  • Crie propriedades que geram uma notificação de alteração.

  • Use o componente em uma página e vincule a eventos do componente.

A visão geral fornece um exemplo de um timer como um componente cliente não visual.O timer gera eventos que você pode manipular.

Este tópico se concentra em objetos com base em componente de cliente não visual.Esses componentes derivam de Component e normalmente não têm representação de interface do usuário.Há dois tipos adicionais de objetos de componentes de cliente ASP.NET AJAX que estendem a funcionalidade dos componentes básicos: comportamentos que derivam de Sys.UI.Behaviore controles que derivam de Sys.UI.controle.A tabela a seguir resume as diferenças entre componentes, comportamentos e controles.

Tipos de Objeto Componente Cliente

Resumo

Componentes

  • Derivam a partir da classe base Component.

  • Geralmente têm nenhuma representação interface do usuário, como um componente de timer que gera eventos em intervalos mas não está visível na página.

  • Não têm nenhum elemento DOM associado.

  • Encapsular código do cliente que deve ser reutilizável para todos os aplicativos.

Comportamentos

  • Derivado da classe base Behavior, que estende a classe base Component.

  • Estende o comportamento de elementos DOM, como um comportamento marca d´água que pode ser anexado a um caixa de texto existente.

  • Pode criar elementos de interface do usuário, embora eles normalmente não modificam o comportamento básico do elemento DOM ao qual eles estão associados.

  • Pode ser acessado diretamente do elemento DOM por meio de um atributo personalizado (expando).O atributo terá o nome do comportamento se uma foi conjunto; caso contrário, ele terá tipo nome (não totalmente qualificado).

  • Não é necessário uma associação com outro objeto do cliente, como uma classe derivada das classes Control ou Behavior.

  • Pode fazer referência a um controle ou um elemento HTML não controle em suas propriedades elemento.

Controles

  • Derivado da classe base Control, que estende a classe base Component.

  • Representa um elemento DOM como um objeto de cliente, normalmente alterarando o comportamento comum do elemento DOM original para fornecer nova funcionalidade.Por exemplo, um controle de menu pode ler itens li de um elemento ul como o dados de origem, mas não exibir uma lista com marcadores.

  • São acessados a partir do elemento DOM diretamente por meio de controle expando.

Pré-requisitos

Para executar o exemplo contidos neste tópico, você precisará:

Criando funcionalidade básica de um componente de cliente não visual

Um componente cliente não visual ASP.NET AJAX encapsula o código JavaScript que destina-se a ser reutilizável para todos os aplicativos.Um exemplo de um componente não visual é um componente de timer que gera eventos em intervalos definidos.

Pela derivação a partir da classe base Component, o componente personalizado automaticamente herda os seguintes recursos:

  • Um modelo de navegador cruzado para gerenciar o manipulador que liga eventos de objeto do cliente.

  • Registro automático do componente no aplicativo cliente como um objeto descartável que implementa a interface Sys.IDisposable.

  • A capacidade de disparar eventos de notificação quando as propriedades são alteradas.

  • A capacidade de realizar processamento em lotes de configurações de propriedades de controle.Isso é mais eficiente no tamanho do script e tempo processamento do que o tratamento de toda a lógica nos acessores get e set de propriedades individuais.

  • Uma substituição do método Sys.Component.initialize para inicializar quaisquer propriedades e ouvintes de eventos.

Implementar um componente de cliente derivado da classe de componente

Para implementar um componente cliente personalizado derivado de Component, siga estas etapas:

  • Defina uma classe de componente usando o padrão de design de protótipo.

  • Inicialize a instância Component base do componente.

  • Expor quaisquer assessores de propriedade, e opcionalmente, elevar um evento de notificação propertyChanged.

  • Substituir o método Dispose para liberar recursos, como limpar manipuladores de eventos.

As seções a seguir fornecem detalhes sobre etapas de implementação.

Definindo uma classe de componente usando o padrão de design de protótipo

Uma classe de cliente ASP.NET AJAX, que inclui uma classe de componente, é definida no JavaScript usando o padrão de design de protótipo.Para definir uma classe de componente usando o padrão de design de protótipo, você faça o seguinte:

  • Registre o namespace para a classe de componente.

  • Criar o componente do construtor função, na função de construtor, definir quaisquer campos particulares e definir seus valores iniciais.

  • Defina protótipo do componente.

  • Registre a função do componente como uma classe derivada de Component.

Para obter mais informações, consulte Criando uma Classe de Componente de Cliente Usando o Modelo Protótipo.

Inicializando a Classe Base

Na função de construtor do componente, você chama o método herdado Type.initializeBase para inicializar o tipo base de sua classe registrada.Uma classe de componente não visual está registrado como uma classe que tenha um tipo base de Component.Quando a classe base Component é inicializada, seus métodos estão disponíveis para o componente, e ele registra automaticamente o componente como um objeto descartável com o aplicativo ASP.NET AJAX habilitado.Para obter mais informações, consulte Interface sys.IDisposable.

Qualquer classe de componente que é derivado de Component deve inicializar sua classe base a partir do construtor.Normalmente você chama initializeBase antes de executar qualquer outro código no construtor.O exemplo a seguir mostra a função contrutor de um componente não visual que é derivado de Component.

Samples.SimpleComponent = function()
{
    Samples.SimpleComponent.initializeBase(this);
}

Definindo Propriedades e Disparando Notificações de Alteração de Propriedade

Você define as propriedades em sua classe de componente que página os desenvolvedores podem obter e definir.Um componente AJAX ASP.NET que é derivado de Component herda o método Sys.Component.raisePropertyChanged, que você chamar para elevar um evento propertyChanged Propriedades do seu componente.Desenvolvedores de página que usam o componente podem então vincular a esses eventos.Para obter mais informações, consulte Definindo Propriedades de Componente Personalizadas e Disparando Eventos PropertyChanged.

Inicializar Propriedades e Ouvintes de Eventos (Event Listeners)

Se o componente personalizado deve inicializar quaisquer propriedades ou ouvintes de eventos, você deve substituir o método Sys.Component.Initialize em protótipo do componente.Por exemplo, um componente não visual que é derivado de Component pode atribuir um delegado a um evento, como window.onFocus.Como uma etapa final, você chama o método initialize base para ativar o componente do classe base para concluir a inicialização.

O ASP.NET fornece as classes e métodos para fornecer gerenciamento de eventos padrão para componentes e elementos DOM.Para gerenciar eventos do seu componente, use a classe Sys.EventHandlerList.Por exemplo, vincular eventos usando o método Sys.EventHandlerList.addHandler e lançando-os usando o método Sys.EventHandlerList.removeHandler.Para obter mais informações, consulte Classe Sys.EventHandlerList.

Para gerenciar os manipuladores de eventos para elementos DOM ou para objeto window, use a classe Sys.UI.DomEvent.Por exemplo, você pode vincular e desvincular manipuladores de eventos usando métodos Sys.UI.DomEvent addHandler e Sys.UI.DomEvent removeHandler.Para obter mais informações, consulte Classe Sys.UI.DomEvent.

Liberando recursos

Se o controle personalizado deve liberar recursos antes do controle ser descartado, substituir o método dispose e liberar os recursos no método substituído.Isso assegura que os recursos são liberados imediatamente antes do componente ser destruído.Recursos que devem ser liberados podem incluir os manipuladores de eventos DOM.Verificando se quaisquer possíveis referências circulares entre elementos DOM e o componente objeto foram removidas, você certifica-se de que o objeto pode ser removido da memória.Para obter mais informações, consulte Liberando Recursos de Componentes.

Usando um componente não visual em uma página

Para usar um controle de cliente personalizado em uma página da Web ASP.NET, faça o seguinte:

  • Registrar a Biblioteca de Script do componente na página da Web.

  • Crie uma instância do componente.

As seções a seguir fornecem detalhes sobre essas etapas.

Registrar a Biblioteca de Script do componente na página da Web.

Você pode registrar os scripts necessários para um controle de cliente na página com um controle ScriptManager, declarativamente ou por meio de programação.O exemplo a seguir mostra a marcação declarativa para um controle ScriptManager que registra um script de componente.

<form id="form1" >
  <asp:ScriptManager  ID="ScriptManager01">
    <scripts>
      <asp:ScriptReference path="DemoTimer.js" />
    </scripts>
  </asp:ScriptManager>
</form>

O elemento asp:ScriptManager contém um elemento asp:ScriptReference dentro de um nó scripts.The path atributo das asp:ScriptReference elemento referencia o caminho do arquivo .js (no exemplo, DemoTimer.js) que define uma classe de componente. Para obter mais informações, consulte Atribuindo Referências a Scripts Dinamicamente e a visão geral da classe ScriptManager .

Como uma alternativa para registrar os arquivos de script usando o controle ScriptManager, você pode gerenciar os componentes do cliente usando um controle de servidor personalizado que implementa a interface IScriptControl.O controle de servidor personalizado pode registrar os scripts de componente necessários automaticamente e expor marcação declarativa para configuração de propriedades do componente e vinculações de eventos.Se você registrar scripts usando um controle de servidor personalizado, você pode facilitar para o desenvolvedor de página a usar seu componente.Para obter mais informações, consulte a visão geral da classe IScriptControl.

Observação:

Todos os arquivos de script autônomo a ser registrados com o controle ScriptManager devem chamar o método notifyScriptLoaded para notificar o aplicativo que o script terminou o carregamento.Scripts incorporados em um conjunto de módulos (assembly) não devem chamar este método na maioria dos casos.Para obter mais informações, consulte Método Sys.Aplicativo.notifyScriptLoaded.

Criando uma instância de componente personalizado

Você instancia um componente cliente chamando o método Sys.Component.create ou o atalho $create.Você passar parâmetros para o método $create para especificar o tipo de componente.Você também passa um objeto JSON que contém um valor de identificação necessário e valores de propriedade inicial opcional e ligações de manipulador de eventos opcional.

O exemplo a seguir mostra como instanciar uma instância de componente chamando o método $create.

var app = Sys.Application;
app.add_init(applicationInitHandler);

function applicationInitHandler(sender, args) 
{
    $create(Demo.Timer, {enabled:true,id:"demoTimer1", interval:2000}, 
        {tick:OnTick}, null);
}

Para obter mais informações, consulte Método Sys.componente.Criar e $ Sys.componente criar método.

Criar o componente Demo.Timer personalizado

Nesta seção, você irá criar um componente de cliente personalizado chamado Demo.Timer que estende o Component classe base e use o componente em uma página. Demo.Timer é um componente timer simples que define um tick evento, expõe um enabled propriedade e um interval propriedade e dispara um evento de notificação de alterar para o interval propriedade. Um desenvolvedor de página que usa o componente Demo.Timer pode manipular o evento tick.O desenvolvedor também pode vincular ao evento de propriedade alterada e tomar a ação sempre que a propriedade interval é atualizada.

Criar o código para o componente Demo.Timer

  1. No diretório raiz de um site da Web ASP.NET com AJAX babilitado, crie um arquivo denominado DemoTimer.js.

  2. Adicione o seguinte código ao arquivo:

    Type.registerNamespace("Demo");
    
    Demo.Timer = function() {
        Demo.Timer.initializeBase(this);
    
        this._interval = 1000;
        this._enabled = false;
        this._timer = null;
    }
    
    Demo.Timer.prototype = {
        // OK to declare value types in the prototype
    
    
        get_interval: function() {
            /// <value type="Number">Interval in milliseconds</value>
            return this._interval;
        },
        set_interval: function(value) {
            if (this._interval !== value) {
                this._interval = value;
                this.raisePropertyChanged('interval');
    
                if (!this.get_isUpdating() && (this._timer !== null)) {
                    this._restartTimer();
                }
            }
        },
    
        get_enabled: function() {
            /// <value type="Boolean">True if timer is enabled, false if disabled.</value>
            return this._enabled;
        },
        set_enabled: function(value) {
            if (value !== this.get_enabled()) {
                this._enabled = value;
                this.raisePropertyChanged('enabled');
                if (!this.get_isUpdating()) {
                    if (value) {
                        this._startTimer();
                    }
                    else {
                        this._stopTimer();
                    }
                }
            }
        },
    
        // events
        add_tick: function(handler) {
            /// <summary>Adds a event handler for the tick event.</summary>
            /// <param name="handler" type="Function">The handler to add to the event.</param>
            this.get_events().addHandler("tick", handler);
        },
        remove_tick: function(handler) {
            /// <summary>Removes a event handler for the tick event.</summary>
            /// <param name="handler" type="Function">The handler to remove from the event.</param>
            this.get_events().removeHandler("tick", handler);
        },
    
        dispose: function() {
            // call set_enabled so the property changed event fires, for potentially attached listeners.
            this.set_enabled(false);
            // make sure it stopped so we aren't called after disposal
            this._stopTimer();
            // be sure to call base.dispose()
            Demo.Timer.callBaseMethod(this, 'dispose');
        },
    
        updated: function() {
            Demo.Timer.callBaseMethod(this, 'updated');
            // called after batch updates, this.beginUpdate(), this.endUpdate().
            if (this._enabled) {
                this._restartTimer();
            }
        },
    
        _timerCallback: function() {
            var handler = this.get_events().getHandler("tick");
            if (handler) {
                handler(this, Sys.EventArgs.Empty);
            }
        },
    
        _restartTimer: function() {
            this._stopTimer();
            this._startTimer();
        },
    
        _startTimer: function() {
            // save timer cookie for removal later
            this._timer = window.setInterval(Function.createDelegate(this, this._timerCallback), this._interval);
        },
    
        _stopTimer: function() {
            if(this._timer) {
                window.clearInterval(this._timer);
                this._timer = null;
            }
        }
    }
    
    Demo.Timer.registerClass('Demo.Timer', Sys.Component);
    
    // Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
    // invoke Sys.Application.notifyScriptLoaded to notify ScriptManager 
    // that this is the end of the script.
    if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
    
    

Discussão de Código

O código registra o namespace Demo chamando o método Type.registerNamespace.É recomendável que você declare e inicializar todos os campos particulares no construtor, como interval nesse exemplo.O construtor chama o método initializeBase herdado para que os métodos da classe base Component fiquem disponíveis.A classe base inicializada, por sua vez, registra a instância Demo.Timer com o aplicativo cliente como um objeto descartável.

No protótipo, o código declara e inicializa duas propriedades públicas: interval e enabled.As definições de propriedade incluem campos particulares para manter seus valores, obter e definir os assessores para cada propriedade.No método de assessor de configuração para cada propriedade pública, o código gera um evento propertyChanged invocando o método raisePropertyChanged.Esse evento informa desenvolvedores de página toda vez que a propriedade for alterada.

Os métodos add_tick e remove_tick habilitam um desenvolvedor de página para adicionar e remover os métodos que escutarão o evento tick.Esses métodos por sua vez adicionam ou removem o manipulador especificado por meio da coleção Sys.EventHandlerList do componente.O objeto EventHandlerList contém uma coleção de manipuladores de eventos do componente através da propriedade herdada Sys.Component.Events.No exemplo, o código chama os métodos Sys.EventHandlerList.addHandler e Sys.EventHandlerList.removeHandler do objeto EventHandlerList retornado para adicionar ou remover o manipuladore.

A classe Demo.Timer substitui o classe base do método dispose para atualizar a propriedade enabled e indicar aos consumidores que o componente foi desativado.O assessor de configuração para a propriedade enabled gera o evento propertyChanged para enviar a notificação.O código chama o método particular _stopTimer para interromper eventos tick de que está sendo gerado.Finalmente, o código chama o método base dispose base para permitir que o aplicativo libere o componente.

Usando o componente Demo.Timer em uma página da Web

Instâncias de componentes de cliente do ASP.NET AJAX em uma página podem ser gerenciadas por um controle de servidor personalizado ou usando script de cliente na página da Web.Nesta seção, você aprenderá como criar uma instância de controle usando script de cliente em uma página da Web.

Criar uma página para usar o componente Demo.Timer

  1. Na pasta onde você colocar o arquivo DemoTimer.js, crie um arquivo denominado DemoTimer.aspx e adicione a seguinte marcação e código para ele:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head >
            <title>Demo Timer Component</title>
    </head>
    <body>
        <form id="form1" > 
            <div>
                <asp:ScriptManager ID="ScriptManager1" >
                    <Scripts>
                        <asp:ScriptReference Path="DemoTimer.js"/>
                    </Scripts>
                </asp:ScriptManager>
    
                Timer Tick Count: <span id="result">0</span>
            </div>
    
            <script type="text/javascript">
    
                function OnTick(sender, args) {
                    var result = $get("result");
                    result.innerText = parseInt(result.innerText) + 1;
                }
    
                 var app = Sys.Application;
                 app.add_init(applicationInitHandler);
    
                 function applicationInitHandler(sender, args) {
                    // Create the DemoTimer component instance.  
                    // Set properties and bind events.
                    $create(Demo.Timer, 
                        {enabled:true,id:"demoTimer1",interval:2000}, 
                        {tick:OnTick}, null, null);
                }
    
            </script> 
        </form>
    </body>
    </html>
    
  2. Na mesma pasta, crie um arquivo denominado TestDemoTimer.js e adicione o seguinte código para ele:

    function OnTick(sender, args) {
        var result = $get("result");
        result.innerText = parseInt(result.innerText) + 1;
    }
    
     var app = Sys.Application;
     app.add_init(applicationInitHandler);
    
     function applicationInitHandler(sender, args) {
        // Create the DemoTimer component instance.  
        // Set properties and bind events.
        $create(Demo.Timer, 
            {enabled:true,id:"demoTimer1",interval:2000}, 
            {tick:OnTick}, null, null);
    }
    

Discussão de Código

A página exemplo carrega o TestDemoTimer.js usando código JavaScript que contém duas funções, OnTick e applicationInitHandler.A função OnTick lida com o Demo.Timer evento tick do componente e atualiza um valor do contador em um elemento HTML span.

A função applicationInitHandler é um manipulador para o evento app_init.Na função, o componente Demo.Timer é instanciado em script de cliente ao chamar o método $create, passando os seguintes argumentos:

  • O argumento type é a classe Demo.Timer que você criou anteriormente.

  • O argumento properties consiste de um objeto JSON que contém o valor de identificação do componente necessário, seguido por pares de propriedades de nome/valor que especificam nomes de propriedades com valores iniciais.Para fins de demonstração, a propriedade interval inicialmente é definida como 2000 milissegundos para que o timer gere um evento tick a cada 2 segundos.(Em um aplicativo de produção, você poderia provavelmente definir o intervalo para um valor maior para reduzir o tráfego de rede.) A propriedade enabled do componente é definida como true assim o timer iniciar imediatamente após ele ser instanciado.

  • O argumento events contém um objeto que contém nomes de eventos combinados com seus identificadores.Nesse caso, o manipulador onTick é atribuído ao evento tick, que é definido na página do elemento script.

O arquivo DemoTimer.aspx é um página da Web do ASP.NET que hospeda o componente.Da página ScriptManager controle, o caminho atributo de do asp:ScriptReference elemento referencia o caminho do arquivo DemoTimer.js que define o Demo.Timer classe de componente.

Consulte também

Tarefas

Atribuindo Referências a Scripts Dinamicamente

Conceitos

Usando o controle ASP.NET UpdatePanel com controles associado a dados

Trabalhando com eventos PageRequestManager

Referência

Sys. Classe de Componente

ScriptManager