view Lib/IMPL/Web/View/TTFactory.pm @ 183:2184fa28b49e

IMPL::Web::View::TTLoader tests
author cin
date Wed, 28 Mar 2012 17:28:51 +0400
parents 47dac58691ee
children 6c0fee769b0c
line wrap: on
line source

package IMPL::Web::View::TTFactory;
use strict;

use Template::Context();

use IMPL::lang qw(:hash :declare :constants);
use IMPL::Exception();


use parent qw(IMPL::Object::Factory);

BEGIN {
	public property template => PROP_ALL;
	public property context => PROP_ALL;
	public property opts => PROP_ALL;
	public property nodeProperties => PROP_ALL;
	public property instances => PROP_GET | PROP_OWNERSET;
}

__PACKAGE__->PassThroughArgs;

sub CTOR {
	my ($this,$factory,$template,$context,$options,$nodeProps) = @_;
	
	die IMPL::ArgumentException("A template is required") unless $template;
	
	$options ||= {};
	
	$this->template($template);
	$this->context($context || new Template::Context($options));
	$this->opts($options);
	$this->nodeProperties($nodeProps || {});
	$this->instances(0);
	
	# init factory context
	$this->context->process($this->template);
}

our %CTOR = (
	'IMPL::Object::Factory' => sub {
		$_[0]
	}
);

sub MergeParameters {
	my ($this,$name,$refProps) = @_;
	
	my $opts = { $this->opts };
	$opts->{STASH} = $opts->{STASH}->clone() if $opts->{STASH};
	
	my $ctx = new Template::Context($opts);
	
	return ($name, $this->template, $ctx, hashMerge($this->nodeProperties,$refProps));
}

sub CreateObject {
	my $this = shift;
	
	my $count = $this->instances;
	
	unless($count) {
		# нужно выполнить именно блок INIT шаблона при создании первого экземпляра
		if (my $init = $this->template->blocks->{INIT}) {
			$this->context->process($init);
		}
	}
	
	$count++;
	$this->instances($count);
	
	return $this->SUPER::CreateObject(@_);
}

sub save {
	die new IMPL::NotImplementedException("This class doesn't support serialization");
}

sub restore {
	die new IMPL::NotImplementedException("This class doesn't support serialization");
}

1;

__END__

=pod

=head1 NAME

C<IMPL::Web::View::TTFactory> - фабрика элементов управления

=head1 SYNOPSIS

=begin code

my $factory = new IMPL::Web::View::TTFactory(
	typeof IMPL::Web::View::TTControl,
	$doc,
	$context,
	{
		TRIM => 1
	},
	{
		myprop => 'my value'
	},
);

my $input1 = $factory->new('login', { class => "required" } );

my $propval = $input->nodeProperty('myprop'); # 'my value'

=end code

=begin text

[%
	this.appendChild(
		my.org.input.new('login', class = this.errors('login') ? "invalid" : "" )
	);
%]

=end text

=head1 DESCRIPTION

C< Inherits L<IMPL::Object::Factory> >

=head1 MEMBERS

=over

=item C<[get,set]template>

Документ C<Template::Document> который описывает элемент управления. См. C<IMPL::Web::View::TTControl>.

=item C<[get,set]context>

Контекст фабрики элементов управления, в этом контексте выполняет шаблон элемента управления при загрузке.
Далее в этом контексте будет выполнен блок инициализации при создании первого элемента управления.

=item C<[get,set]opts>

Параметры контекста элемента управления (ссылка на хеш). Каждый элемент управления при создании получает свой контекст,
который создает с данными параметрами и хранилищем переменных, дочерним к контексту фабрики.

=item C<[get,set]nodeProperties>

Ссылка на хеш со значениями свойств по умолчанию для создаваемого элемента управления.

=item C<[get]instances>

Количество созданных элементов управления данной фабрикой

=item C<[override]MergeParameters($name,$nodeProps)>

Превращает значения переданные методу C<new> фабрики в параметры для создания элемента управления.

=over

=item C<$name>

Имя создаваемого узла (C<nodeName>).

=item C<$nodeProps>

Ссылка на шех со значениями свойств узла. Данные значения будут совмещены со значениями из свойства C<nodeProperties>

=back

=item C<[override]CreateObject(@params)>

Создает экземпляр элемента управления стандартным образом. Учитывает количество экземпляров и если это первый,
то производит дополнительную инициализацию контекста выполнив блок шаблона C<INIT>.

=item C<new($name,$nodeProps)>

Создает элемент управления с указанным именем и набором свойств. 

=back

=cut