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