Mercurial > pub > Impl
view Lib/IMPL/Web/View/TTControl.pm @ 192:a9faf883cdce
IMPL::Web::View refactoring
author | cin |
---|---|
date | Fri, 06 Apr 2012 16:22:38 +0400 |
parents | 78a18a2b6266 |
children | 4d0e1962161c |
line wrap: on
line source
package IMPL::Web::View::TTControl; use strict; use IMPL::DOM::Property qw(_dom); use IMPL::lang qw(:declare :constants); use Template::Context(); use Scalar::Util qw(weaken); use parent qw( IMPL::DOM::Node ); { my $nextId = 1; sub _GetNextId { return $nextId++; } } BEGIN { public _dom property id => PROP_ALL; public property context => PROP_GET | PROP_OWNERSET; public property template => PROP_ALL; } sub CTOR { my ($this,$name,$template,$context,$refProps) = @_; $name ||= "control"; $this->template( $template ) or die new IMPL::ArgumentException("A template is required"); $this->context( $context ) or die new IMPL::ArgumentException("A context is required"); $this->id($name . "-" . _GetNextId()) unless $this->id; weaken($this); # prevent cyclic references produces by the code below $context->stash->set('append', sub { $this->appendChild(@_); undef; } ); $context->stash->set('select', sub { $this->selectNodes(@_); } ); } our %CTOR = ( 'IMPL::DOM::Node' => sub { nodeName => $_[0], %{ $_[3] || {} } } ); sub InitInstance { my ($this,$args) = @_; $args ||= {}; if ( my $ctor = $this->template->blocks->{CTOR} ) { $this->context->process($ctor, { %$args, this => $this } ); $this->context->stash->set('this',undef); } } sub renderBlock { $_[0]->template->blocks->{RENDER} || $_[0]->template; } sub Render { my ($this,$args) = @_; $args = {} unless ref $args eq 'HASH'; if(my $body = $this->renderBlock ) { return $this->context->include( $body, { %$args, this => $this, template => $this->template, document => $this->document } ); } else { return ""; } } sub AUTOLOAD { our $AUTOLOAD; my $method = ($AUTOLOAD =~ m/(\w+)$/)[0]; return if $method eq 'DESTROY'; my $this = shift; $this->nodeProperty($method,@_); } 1; __END__ =pod =head1 NAME C<IMPL::Web::View::TTControl> =head1 SYNPOSIS =head1 DESCRIPTION =head2 BLOCKS При загрузке шаблона, создается фабрика, с собственным контекстом в которой выполняется шаблон элемента управления =head3 INIT Данный блок шаблона управления выполняется один раз при создании первого экземпляра элемента управления =head3 CTOR данный блок выполняется каждый раз при создании нового экземпляра элемента управления, при этом переменная C<this> указывает на эземпляр элемента упарвления =head3 RENDER Данный блок выполняется при вызове метода C<Render()>, вывод данного блока и есть результат отображения элемента управления. =head2 TEMPLATE VARS Каждый шаблон имеет собственное пространство имен, унаследованное от пространства имен фабрики элементов (которая в свою очередь наследует контекст документа). В шаблоне могут определяться новые переменные, которые разделяются между блоками. Также доступны стандартные переменные =over =item * C<this> ссылка на объект элемента управления =item * C<component> ссылка на текущий шаблон, устанавливается автоматически в методе C<Template::Context::process>. =item * C<template> ссылка на шаблон элемента управления, для совместимости с C<TT> =back =head1 MEMBERS =over =item * C<[get]context> Контекст элемента управления, хранит пременные шаблона. Наследуется от контекста фабрики элементов управления, который наследуется от контекста документа. =item * C<[get,set]template> C<Template::Document> Шаблон элемента управления. =item * C<AUTOLOAD> Для удобства работы с шаблоном, элементы управления предоставляю доступ к своим свойствам через метод C<AUTOLOAD>. =back C<lang ru> =cut