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