view Lib/IMPL/Web/View/TTFactory.pm @ 245:7c517134c42f

Added Unsupported media type Web exception corrected resourceLocation setting in the resource Implemented localizable resources for text messages fixed TT view scopings, INIT block in controls now sets globals correctly.
author sergey
date Mon, 29 Oct 2012 03:15:22 +0400
parents 5c82eec23bb6
children bbc0da7ef90e
line wrap: on
line source

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

use Template::Context();

use IMPL::lang qw(:hash :declare );
use IMPL::Exception();
use Scalar::Util qw(weaken);


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 ||= {};
    $context ||= new Template::Context($options);
    
    $this->template($template);
    $this->context($context);
    $this->opts($options);
    $this->nodeProperties($nodeProps || {});
    $this->instances(0);
}

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);
        }
    }
    
    my $instance = $this->SUPER::CreateObject(@_);
    
    $instance->InitInstance();
    
    $count++;
    $this->instances($count);
    
    return $instance;
}

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<[inherited]new($name,$nodeProps)>

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

=back

=cut