Mercurial > pub > Impl
annotate Lib/IMPL/Web/View/TTFactory.pm @ 296:86ff93b34f2a
sync
| author | cin |
|---|---|
| date | Tue, 05 Mar 2013 01:46:32 +0400 |
| parents | 5d14baa35790 |
| children | 78f767765706 |
| rev | line source |
|---|---|
| 181 | 1 package IMPL::Web::View::TTFactory; |
| 2 use strict; | |
| 3 | |
| 4 use Template::Context(); | |
| 5 | |
| 267 | 6 use IMPL::lang qw(:hash); |
| 181 | 7 use IMPL::Exception(); |
| 192 | 8 use Scalar::Util qw(weaken); |
| 181 | 9 |
| 10 | |
| 267 | 11 use IMPL::Const qw(:prop); |
| 12 use IMPL::declare { | |
| 13 base => [ | |
| 14 'IMPL::Object::Factory' => '@_' | |
| 15 ], | |
| 16 props => [ | |
| 17 template => PROP_RW, | |
| 18 context => PROP_RW, | |
| 19 instances => PROP_RW, | |
|
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
20 base => PROP_RW, |
|
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
21 require => PROP_RO |
| 267 | 22 ] |
| 23 }; | |
| 181 | 24 |
| 25 sub CTOR { | |
|
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
26 my ($this,$factory,$template,$context,$base,$require) = @_; |
| 194 | 27 |
| 28 die IMPL::ArgumentException("A template is required") unless $template; | |
| 29 | |
| 287 | 30 $context ||= new Template::Context(); |
| 194 | 31 |
| 32 $this->template($template); | |
| 33 $this->context($context); | |
| 267 | 34 $this->base($base); |
| 194 | 35 $this->instances(0); |
|
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
36 $this->require($require); |
| 181 | 37 } |
| 38 | |
| 39 our %CTOR = ( | |
| 194 | 40 'IMPL::Object::Factory' => sub { |
| 41 $_[0] | |
| 42 } | |
| 181 | 43 ); |
| 44 | |
| 45 sub MergeParameters { | |
| 194 | 46 my ($this,$name,$refProps) = @_; |
| 47 | |
| 291 | 48 if (ref $name) { |
| 49 $refProps = $name; | |
| 50 $name = (ref $refProps eq 'HASH' and ($refProps->{name} || $refProps->{id})) || '*anonymous*'; | |
| 51 } | |
| 52 | |
| 267 | 53 my $base = $this->base; |
| 54 | |
| 287 | 55 $this->context->localise(); |
| 56 | |
| 289 | 57 my $ctx = _clone_context($this->context); |
| 287 | 58 |
| 59 $this->context->delocalise(); | |
| 194 | 60 |
| 267 | 61 my $stash = $ctx->stash; |
|
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
62 my $require = $this->require; |
| 289 | 63 |
| 290 | 64 |
| 267 | 65 $stash->update({ |
| 66 require => sub { | |
| 67 my ($module) = @_; | |
| 68 | |
| 69 $module =~ s/^\.\//$base\//; | |
|
288
3a9cfea098dd
*TTView refactoring: removed RequireControl method, etc.
sergey
parents:
287
diff
changeset
|
70 return $require->($module); |
| 267 | 71 } |
| 72 }); | |
| 73 | |
| 289 | 74 return ($name, $this->template, $ctx, $refProps); |
| 181 | 75 } |
| 76 | |
| 77 sub CreateObject { | |
| 194 | 78 my $this = shift; |
| 79 | |
| 80 my $count = $this->instances; | |
| 81 | |
| 82 unless($count) { | |
| 83 # нужно выполнить именно блок INIT шаблона при создании первого экземпляра | |
| 84 if (my $init = $this->template->blocks->{INIT}) { | |
| 85 $this->context->process($init); | |
| 86 } | |
| 296 | 87 |
| 88 $this->context->visit($this->template->blocks); | |
| 194 | 89 } |
| 90 | |
| 91 my $instance = $this->SUPER::CreateObject(@_); | |
| 92 | |
| 93 $instance->InitInstance(); | |
| 94 | |
| 95 $count++; | |
| 96 $this->instances($count); | |
| 97 | |
| 98 return $instance; | |
| 181 | 99 } |
| 100 | |
| 289 | 101 sub _clone_context { |
| 102 my $args = { %{shift || {}} }; | |
| 103 delete $args->{CONFIG}; | |
| 104 | |
| 105 return Template::Context->new($args); | |
| 106 } | |
| 107 | |
| 181 | 108 sub save { |
| 194 | 109 die new IMPL::NotImplementedException("This class doesn't support serialization"); |
| 181 | 110 } |
| 111 | |
| 112 sub restore { | |
| 194 | 113 die new IMPL::NotImplementedException("This class doesn't support serialization"); |
| 181 | 114 } |
| 115 | |
| 116 1; | |
| 117 | |
| 118 __END__ | |
| 119 | |
| 120 =pod | |
| 121 | |
| 122 =head1 NAME | |
| 123 | |
| 124 C<IMPL::Web::View::TTFactory> - фабрика элементов управления | |
| 125 | |
| 126 =head1 SYNOPSIS | |
| 127 | |
| 128 =begin code | |
| 129 | |
| 130 my $factory = new IMPL::Web::View::TTFactory( | |
| 280 | 131 'IMPL::Web::View::TTControl', |
| 194 | 132 $doc, |
| 133 $context, | |
| 134 { | |
| 135 TRIM => 1 | |
| 136 }, | |
| 137 { | |
| 138 myprop => 'my value' | |
| 139 }, | |
| 181 | 140 ); |
| 141 | |
| 142 my $input1 = $factory->new('login', { class => "required" } ); | |
| 143 | |
| 144 my $propval = $input->nodeProperty('myprop'); # 'my value' | |
| 145 | |
| 146 =end code | |
| 147 | |
| 148 =begin text | |
| 149 | |
| 150 [% | |
| 194 | 151 this.appendChild( |
| 152 my.org.input.new('login', class = this.errors('login') ? "invalid" : "" ) | |
| 153 ); | |
| 181 | 154 %] |
| 155 | |
| 156 =end text | |
| 157 | |
| 158 =head1 DESCRIPTION | |
| 159 | |
| 160 C< Inherits L<IMPL::Object::Factory> > | |
| 161 | |
| 162 =head1 MEMBERS | |
| 163 | |
| 164 =over | |
| 165 | |
| 166 =item C<[get,set]template> | |
| 167 | |
| 168 Документ C<Template::Document> который описывает элемент управления. См. C<IMPL::Web::View::TTControl>. | |
| 169 | |
| 170 =item C<[get,set]context> | |
| 171 | |
| 172 Контекст фабрики элементов управления, в этом контексте выполняет шаблон элемента управления при загрузке. | |
| 173 Далее в этом контексте будет выполнен блок инициализации при создании первого элемента управления. | |
| 174 | |
| 175 =item C<[get,set]opts> | |
| 176 | |
| 177 Параметры контекста элемента управления (ссылка на хеш). Каждый элемент управления при создании получает свой контекст, | |
| 178 который создает с данными параметрами и хранилищем переменных, дочерним к контексту фабрики. | |
| 179 | |
| 180 =item C<[get,set]nodeProperties> | |
| 181 | |
| 182 Ссылка на хеш со значениями свойств по умолчанию для создаваемого элемента управления. | |
| 183 | |
| 184 =item C<[get]instances> | |
| 185 | |
| 186 Количество созданных элементов управления данной фабрикой | |
| 187 | |
| 188 =item C<[override]MergeParameters($name,$nodeProps)> | |
| 189 | |
| 190 Превращает значения переданные методу C<new> фабрики в параметры для создания элемента управления. | |
| 191 | |
| 192 =over | |
| 193 | |
| 194 =item C<$name> | |
| 195 | |
| 196 Имя создаваемого узла (C<nodeName>). | |
| 197 | |
| 198 =item C<$nodeProps> | |
| 199 | |
| 200 Ссылка на шех со значениями свойств узла. Данные значения будут совмещены со значениями из свойства C<nodeProperties> | |
| 201 | |
| 202 =back | |
| 203 | |
| 204 =item C<[override]CreateObject(@params)> | |
| 205 | |
| 206 Создает экземпляр элемента управления стандартным образом. Учитывает количество экземпляров и если это первый, | |
| 207 то производит дополнительную инициализацию контекста выполнив блок шаблона C<INIT>. | |
| 208 | |
| 191 | 209 =item C<[inherited]new($name,$nodeProps)> |
| 181 | 210 |
| 211 Создает элемент управления с указанным именем и набором свойств. | |
| 212 | |
| 213 =back | |
| 214 | |
| 215 =cut |
