Mercurial > pub > Impl
annotate Lib/IMPL/Web/View/TTFactory.pm @ 291:5d14baa35790
*TTView: fixed template selectors mechanism
| author | cin |
|---|---|
| date | Thu, 21 Feb 2013 03:44:02 +0400 |
| parents | 7b0dad6117d5 |
| children | 86ff93b34f2a |
| 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 } | |
| 87 } | |
| 88 | |
| 89 my $instance = $this->SUPER::CreateObject(@_); | |
| 90 | |
| 91 $instance->InitInstance(); | |
| 92 | |
| 93 $count++; | |
| 94 $this->instances($count); | |
| 95 | |
| 96 return $instance; | |
| 181 | 97 } |
| 98 | |
| 289 | 99 sub _clone_context { |
| 100 my $args = { %{shift || {}} }; | |
| 101 delete $args->{CONFIG}; | |
| 102 | |
| 103 return Template::Context->new($args); | |
| 104 } | |
| 105 | |
| 181 | 106 sub save { |
| 194 | 107 die new IMPL::NotImplementedException("This class doesn't support serialization"); |
| 181 | 108 } |
| 109 | |
| 110 sub restore { | |
| 194 | 111 die new IMPL::NotImplementedException("This class doesn't support serialization"); |
| 181 | 112 } |
| 113 | |
| 114 1; | |
| 115 | |
| 116 __END__ | |
| 117 | |
| 118 =pod | |
| 119 | |
| 120 =head1 NAME | |
| 121 | |
| 122 C<IMPL::Web::View::TTFactory> - фабрика элементов управления | |
| 123 | |
| 124 =head1 SYNOPSIS | |
| 125 | |
| 126 =begin code | |
| 127 | |
| 128 my $factory = new IMPL::Web::View::TTFactory( | |
| 280 | 129 'IMPL::Web::View::TTControl', |
| 194 | 130 $doc, |
| 131 $context, | |
| 132 { | |
| 133 TRIM => 1 | |
| 134 }, | |
| 135 { | |
| 136 myprop => 'my value' | |
| 137 }, | |
| 181 | 138 ); |
| 139 | |
| 140 my $input1 = $factory->new('login', { class => "required" } ); | |
| 141 | |
| 142 my $propval = $input->nodeProperty('myprop'); # 'my value' | |
| 143 | |
| 144 =end code | |
| 145 | |
| 146 =begin text | |
| 147 | |
| 148 [% | |
| 194 | 149 this.appendChild( |
| 150 my.org.input.new('login', class = this.errors('login') ? "invalid" : "" ) | |
| 151 ); | |
| 181 | 152 %] |
| 153 | |
| 154 =end text | |
| 155 | |
| 156 =head1 DESCRIPTION | |
| 157 | |
| 158 C< Inherits L<IMPL::Object::Factory> > | |
| 159 | |
| 160 =head1 MEMBERS | |
| 161 | |
| 162 =over | |
| 163 | |
| 164 =item C<[get,set]template> | |
| 165 | |
| 166 Документ C<Template::Document> который описывает элемент управления. См. C<IMPL::Web::View::TTControl>. | |
| 167 | |
| 168 =item C<[get,set]context> | |
| 169 | |
| 170 Контекст фабрики элементов управления, в этом контексте выполняет шаблон элемента управления при загрузке. | |
| 171 Далее в этом контексте будет выполнен блок инициализации при создании первого элемента управления. | |
| 172 | |
| 173 =item C<[get,set]opts> | |
| 174 | |
| 175 Параметры контекста элемента управления (ссылка на хеш). Каждый элемент управления при создании получает свой контекст, | |
| 176 который создает с данными параметрами и хранилищем переменных, дочерним к контексту фабрики. | |
| 177 | |
| 178 =item C<[get,set]nodeProperties> | |
| 179 | |
| 180 Ссылка на хеш со значениями свойств по умолчанию для создаваемого элемента управления. | |
| 181 | |
| 182 =item C<[get]instances> | |
| 183 | |
| 184 Количество созданных элементов управления данной фабрикой | |
| 185 | |
| 186 =item C<[override]MergeParameters($name,$nodeProps)> | |
| 187 | |
| 188 Превращает значения переданные методу C<new> фабрики в параметры для создания элемента управления. | |
| 189 | |
| 190 =over | |
| 191 | |
| 192 =item C<$name> | |
| 193 | |
| 194 Имя создаваемого узла (C<nodeName>). | |
| 195 | |
| 196 =item C<$nodeProps> | |
| 197 | |
| 198 Ссылка на шех со значениями свойств узла. Данные значения будут совмещены со значениями из свойства C<nodeProperties> | |
| 199 | |
| 200 =back | |
| 201 | |
| 202 =item C<[override]CreateObject(@params)> | |
| 203 | |
| 204 Создает экземпляр элемента управления стандартным образом. Учитывает количество экземпляров и если это первый, | |
| 205 то производит дополнительную инициализацию контекста выполнив блок шаблона C<INIT>. | |
| 206 | |
| 191 | 207 =item C<[inherited]new($name,$nodeProps)> |
| 181 | 208 |
| 209 Создает элемент управления с указанным именем и набором свойств. | |
| 210 | |
| 211 =back | |
| 212 | |
| 213 =cut |
