Mercurial > pub > Impl
view Lib/IMPL/Web/View/TTControl.pm @ 250:129e48bb5afb
DOM refactoring
ObjectToDOM methods are virtual
QueryToDOM uses inflators
Fixed transform for the complex values in the ObjectToDOM
QueryToDOM doesn't allow to use complex values (HASHes) as values for nodes (overpost problem)
author | sergey |
---|---|
date | Wed, 07 Nov 2012 04:17:53 +0400 |
parents | f48a1a9f4fa2 |
children | 6b6d4b2275a1 |
line wrap: on
line source
package IMPL::Web::View::TTControl; use strict; use IMPL::Const qw(:prop); use IMPL::lang qw(:hash); use Scalar::Util qw(blessed); use IMPL::declare { require => { TTContext => 'Template::Context', Exception => 'IMPL::Exception', ArgumentException => '-IMPL::InvalidArgumentException', OperationException => '-IMPL::InvalidOperationException' }, base => [ 'IMPL::Object' => undef ], props => [ id => PROP_RO, attributes => PROP_RW, name => PROP_RO, context => PROP_RO, template => PROP_RO ] }; { my $nextId = 1; sub _GetNextId { return $nextId++; } } our $AutoloadRegex = qr/^[a-z]/; our @REFLECT_META = qw(title layout); 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; $this->name($name); $this->attributes({}); my %attrs; foreach my $meta ( @REFLECT_META ) { next if $meta =~ /^_/; if( my $value = $template->$meta() ) { $attrs{$meta} = $value; } } hashApply(\%attrs,$refProps) if ref $refProps eq 'HASH'; while (my($key,$value) = each %attrs) { $this->SetAttribute($key,$value); } } sub InitInstance { my ($this,$args) = @_; $args ||= {}; if ( my $ctor = $this->template->blocks->{CTOR} ) { $this->context->include($ctor, { %$args, this => $this, template => $this->template } ); } } sub GetAttribute { my ($this,$name) = (shift,shift); if (my $method = $this->can($name)) { unshift @_,$this; goto &$method; } else { return $this->attributes->{$name}; } } sub SetAttribute { my $this = shift; my $name = shift; if (my $method = $this->can($name)) { unshift @_, $this; goto &$method; } else { return $this->attributes->{$name} = shift; } } sub GetRenderBlock { $_[0]->template->blocks->{RENDER} || $_[0]->template; } sub Render { my ($this,$args) = @_; $args = {} unless ref $args eq 'HASH'; if(my $body = $this->GetRenderBlock ) { return $this->context->include( $body, { %$args, this => $this, template => $this->template } ); } else { return ""; } } sub AUTOLOAD { our $AUTOLOAD; my $method = ($AUTOLOAD =~ m/(\w+)$/)[0]; return if $method eq 'DESTROY'; if ($method =~ /$AutoloadRegex/) { my $this = shift; die OperationException->new("can't invoke method '$method' on an unblessed reference") unless blessed $this; return @_ ? $this->SetAttribute($method,@_) : $this->GetAttribute($method); } else { die OperationException->new("The specified method '$method' doesn't exists"); } } 1; __END__ =pod =head1 NAME C<IMPL::Web::View::TTControl> =head1 SYNPOSIS =head1 DESCRIPTION =head2 BLOCKS =head3 INIT Данный блок шаблона управления выполняется один раз при создании первого экземпляра элемента управления, может использоваться для формирования заголовочной части документа, скрипта подключающего ajax модули при необходимости и т.п. =head3 CTOR данный блок выполняется каждый раз при создании нового экземпляра элемента управления, при этом переменная C<this> указывает на эземпляр элемента упарвления. Данный блок можно использовать для инициализации свойств элемента управления. =head3 RENDER Данный блок выполняется при вызове метода C<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