Mercurial > pub > Impl
annotate Lib/IMPL/Web/View/TTControl.pm @ 300:bf3af33b9003
sync
author | cin |
---|---|
date | Fri, 22 Mar 2013 01:05:11 +0400 |
parents | bd79145657e5 |
children | aeeb57a12046 |
rev | line source |
---|---|
181 | 1 package IMPL::Web::View::TTControl; |
2 use strict; | |
3 | |
234 | 4 use IMPL::Const qw(:prop); |
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
5 use IMPL::lang qw(:hash); |
299 | 6 use Scalar::Util qw(blessed reftype); |
234 | 7 use IMPL::declare { |
8 require => { | |
296 | 9 TemplateDocument => 'Template::Document', |
234 | 10 TTContext => 'Template::Context', |
11 Exception => 'IMPL::Exception', | |
238 | 12 ArgumentException => '-IMPL::InvalidArgumentException', |
13 OperationException => '-IMPL::InvalidOperationException' | |
234 | 14 }, |
15 base => [ | |
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
16 'IMPL::Object' => undef |
234 | 17 ], |
18 props => [ | |
19 id => PROP_RO, | |
238 | 20 attributes => PROP_RW, |
234 | 21 context => PROP_RO, |
22 template => PROP_RO | |
23 ] | |
24 }; | |
25 | |
181 | 26 |
187 | 27 { |
194 | 28 my $nextId = 1; |
29 sub _GetNextId { | |
299 | 30 return '_' . $nextId++; |
194 | 31 } |
187 | 32 } |
181 | 33 |
300 | 34 our $AUTOLOAD_REGEX = qr/^[a-z]/; |
238 | 35 |
181 | 36 sub CTOR { |
299 | 37 my ($this,$template,$context,$attrs) = @_; |
194 | 38 |
299 | 39 |
194 | 40 $this->template( $template ) or die new IMPL::ArgumentException("A template is required"); |
41 $this->context( $context ) or die new IMPL::ArgumentException("A context is required"); | |
42 | |
238 | 43 $this->attributes({}); |
194 | 44 |
299 | 45 if(reftype($attrs) eq 'HASH') { |
46 while (my($key,$value) = each %$attrs) { | |
47 $this->SetAttribute($key,$value); | |
48 } | |
238 | 49 } |
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
50 |
299 | 51 $this->id(_GetNextId()) unless $this->id; |
191 | 52 } |
53 | |
238 | 54 sub GetAttribute { |
55 my ($this,$name) = (shift,shift); | |
56 | |
57 if (my $method = $this->can($name)) { | |
58 unshift @_,$this; | |
59 goto &$method; | |
60 } else { | |
61 return $this->attributes->{$name}; | |
62 } | |
63 } | |
64 | |
65 sub SetAttribute { | |
66 my $this = shift; | |
67 my $name = shift; | |
68 | |
69 if (my $method = $this->can($name)) { | |
70 unshift @_, $this; | |
71 goto &$method; | |
72 } else { | |
73 return $this->attributes->{$name} = shift; | |
74 } | |
75 } | |
76 | |
187 | 77 sub Render { |
194 | 78 my ($this,$args) = @_; |
79 | |
80 $args = {} unless ref $args eq 'HASH'; | |
81 | |
299 | 82 return $this->context->include( |
83 $this->template, | |
84 { | |
85 %$args, | |
86 this => $this, | |
87 template => $this->template | |
88 } | |
89 ); | |
267 | 90 } |
91 | |
185 | 92 sub AUTOLOAD { |
194 | 93 our $AUTOLOAD; |
94 | |
95 my $method = ($AUTOLOAD =~ m/(\w+)$/)[0]; | |
96 | |
97 return if $method eq 'DESTROY'; | |
98 | |
300 | 99 if ($method =~ /$AUTOLOAD_REGEX/) { |
238 | 100 my $this = shift; |
241
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
101 |
f48a1a9f4fa2
+Added ViewResult to allow implementation of the view environment.
sergey
parents:
238
diff
changeset
|
102 die OperationException->new("can't invoke method '$method' on an unblessed reference") unless blessed $this; |
238 | 103 |
104 return @_ ? $this->SetAttribute($method,@_) : $this->GetAttribute($method); | |
105 } else { | |
106 die OperationException->new("The specified method '$method' doesn't exists"); | |
107 } | |
181 | 108 } |
109 | |
110 1; | |
111 | |
112 __END__ | |
113 | |
114 =pod | |
115 | |
116 =head1 NAME | |
117 | |
118 C<IMPL::Web::View::TTControl> | |
119 | |
120 =head1 SYNPOSIS | |
121 | |
265 | 122 =begin text |
123 | |
124 [% | |
125 META version = 1; | |
126 BLOCK INIT; | |
127 # this is a document scope | |
299 | 128 dojo.modules.push( 'dijit/form/Input' ); |
265 | 129 END; |
299 | 130 |
131 # local to this block | |
132 TPreview = require('My/Org/TextPreview'); | |
265 | 133 |
299 | 134 # init control props |
135 visualClass = this.visualClass || 'classic'; | |
136 %] | |
137 <div id="$id" class="$visualClass" data-dojo-type="dijit/form/Input"> | |
138 [% FOREACH item IN model %] | |
139 <div class="itemContainer"> | |
140 [% Display(item) %] | |
141 </div> | |
265 | 142 [% END %] |
143 </div> | |
144 | |
145 =end text | |
146 | |
181 | 147 =head1 DESCRIPTION |
148 | |
299 | 149 Легкая обертка вокруг шаблона, позволяет изолировать пространство имен шаблона, |
150 а также реализовать собственные методы по представлению данных (в случае если | |
151 это проще сделать в виде методов класса). | |
265 | 152 |
181 | 153 =head2 BLOCKS |
154 | |
265 | 155 =head3 META |
156 | |
157 Атрибуты C<META> C<layout>, C<title> будут перенесены в свойства элемента | |
158 управления. | |
159 | |
181 | 160 =head3 INIT |
161 | |
265 | 162 Данный блок шаблона управления выполняется один раз при создании первого |
163 экземпляра элемента управления, в пространстве имен документа. Может | |
164 использоваться для формирования заголовочной части документа, скрипта | |
165 подключающего C<js> модули и т.п. | |
166 | |
167 Выполнение данного блока производится фабрикой элементов управления. | |
181 | 168 |
187 | 169 =head2 TEMPLATE VARS |
170 | |
265 | 171 Каждый шаблон имеет собственное пространство имен, вложенное в пространство имен |
172 фабрики элементов (которая разделяет пространство имен документа). В шаблоне | |
173 могут определяться новые переменные, однако они останутся локальными для блоков. | |
174 | |
175 Чтобы передать данные между блоками следует использовать ссылку на элемент | |
176 управления C<this>. | |
177 | |
178 =begin text | |
179 | |
180 [% | |
181 BLOCK CTOR; | |
182 this.extraCssClass = 'active'; | |
183 text = "this text will gone"; | |
184 END; | |
185 %] | |
186 | |
187 <div class="$this.extraCssClass">some text $text</div> | |
188 | |
189 =end text | |
190 | |
191 В примере выше переменная C<$text> установленная в конструкторе шаблона, при | |
192 отображении элемента управления будет неопределена. | |
187 | 193 |
194 =over | |
195 | |
265 | 196 =item * C<this> |
197 | |
198 ссылка на объект элемента управления | |
199 | |
200 =item * C<component> | |
187 | 201 |
265 | 202 ссылка на текущий шаблон, устанавливается автоматически в методе |
203 C<Template::Context::process>. | |
187 | 204 |
265 | 205 =item * C<template> |
206 | |
207 ссылка на шаблон элемента управления, для совместимости с C<TT> | |
187 | 208 |
209 =back | |
210 | |
211 =head1 MEMBERS | |
212 | |
300 | 213 =head2 C<[get]context> |
187 | 214 |
300 | 215 Контекст элемента управления, хранит пременные шаблона. Фабрика элементов |
216 управления создает новый контекст пространство имен которого вложено в | |
217 пространство имен документа. | |
187 | 218 |
300 | 219 Контекст следует использовать только при рендеринге документа. |
220 | |
221 =head2 C<[get,set]template> | |
187 | 222 |
223 C<Template::Document> Шаблон элемента управления. | |
224 | |
300 | 225 =head2 C<AUTOLOAD> |
187 | 226 |
265 | 227 Для удобства работы с шаблоном, элементы управления предоставляю доступ к своим |
228 свойствам через метод C<AUTOLOAD>. Имена свойств должны начинаться со строчной | |
229 буквы. | |
187 | 230 |
181 | 231 =cut |