Mercurial > pub > Impl
comparison Lib/IMPL/Web/View/TTControl.pm @ 299:bd79145657e5
sync
author | sergey |
---|---|
date | Thu, 21 Mar 2013 16:00:09 +0400 |
parents | 86ff93b34f2a |
children | bf3af33b9003 |
comparison
equal
deleted
inserted
replaced
298:78f767765706 | 299:bd79145657e5 |
---|---|
1 package IMPL::Web::View::TTControl; | 1 package IMPL::Web::View::TTControl; |
2 use strict; | 2 use strict; |
3 | 3 |
4 use IMPL::Const qw(:prop); | 4 use IMPL::Const qw(:prop); |
5 use IMPL::lang qw(:hash); | 5 use IMPL::lang qw(:hash); |
6 use Scalar::Util qw(blessed); | 6 use Scalar::Util qw(blessed reftype); |
7 use IMPL::declare { | 7 use IMPL::declare { |
8 require => { | 8 require => { |
9 TemplateDocument => 'Template::Document', | 9 TemplateDocument => 'Template::Document', |
10 TTContext => 'Template::Context', | 10 TTContext => 'Template::Context', |
11 Exception => 'IMPL::Exception', | 11 Exception => 'IMPL::Exception', |
16 'IMPL::Object' => undef | 16 'IMPL::Object' => undef |
17 ], | 17 ], |
18 props => [ | 18 props => [ |
19 id => PROP_RO, | 19 id => PROP_RO, |
20 attributes => PROP_RW, | 20 attributes => PROP_RW, |
21 name => PROP_RO, | |
22 context => PROP_RO, | 21 context => PROP_RO, |
23 template => PROP_RO | 22 template => PROP_RO |
24 ] | 23 ] |
25 }; | 24 }; |
26 | 25 |
27 | 26 |
28 { | 27 { |
29 my $nextId = 1; | 28 my $nextId = 1; |
30 sub _GetNextId { | 29 sub _GetNextId { |
31 return $nextId++; | 30 return '_' . $nextId++; |
32 } | 31 } |
33 } | 32 } |
34 | 33 |
35 our $AutoloadRegex = qr/^[a-z]/; | 34 our $AutoloadRegex = qr/^[a-z]/; |
36 our @REFLECT_META = qw(title layout); | |
37 | 35 |
38 sub CTOR { | 36 sub CTOR { |
39 my ($this,$name,$template,$context,$refProps) = @_; | 37 my ($this,$template,$context,$attrs) = @_; |
40 | 38 |
41 $name ||= "control"; | 39 |
42 | |
43 $this->template( $template ) or die new IMPL::ArgumentException("A template is required"); | 40 $this->template( $template ) or die new IMPL::ArgumentException("A template is required"); |
44 $this->context( $context ) or die new IMPL::ArgumentException("A context is required"); | 41 $this->context( $context ) or die new IMPL::ArgumentException("A context is required"); |
45 | 42 |
46 $this->id($name . "-" . _GetNextId()) unless $this->id; | |
47 | |
48 $this->name($name); | |
49 $this->attributes({}); | 43 $this->attributes({}); |
50 | 44 |
51 my %attrs; | 45 if(reftype($attrs) eq 'HASH') { |
52 | 46 while (my($key,$value) = each %$attrs) { |
53 foreach my $meta ( @REFLECT_META ) { | 47 $this->SetAttribute($key,$value); |
54 next if $meta =~ /^_/; | 48 } |
55 if( my $value = $template->$meta() ) { | 49 } |
56 $attrs{$meta} = $value; | 50 |
57 } | 51 $this->id(_GetNextId()) unless $this->id; |
58 } | |
59 | |
60 hashApply(\%attrs,$refProps) if ref $refProps eq 'HASH'; | |
61 | |
62 while (my($key,$value) = each %attrs) { | |
63 $this->SetAttribute($key,$value); | |
64 } | |
65 } | |
66 | |
67 sub InitInstance { | |
68 my ($this,$args) = @_; | |
69 | |
70 $args ||= {}; | |
71 | |
72 if ( my $ctor = $this->template->blocks->{CTOR} ) { | |
73 $this->context->include($ctor, { %$args, this => $this, template => $this->template } ); | |
74 } | |
75 } | 52 } |
76 | 53 |
77 sub GetAttribute { | 54 sub GetAttribute { |
78 my ($this,$name) = (shift,shift); | 55 my ($this,$name) = (shift,shift); |
79 | 56 |
95 } else { | 72 } else { |
96 return $this->attributes->{$name} = shift; | 73 return $this->attributes->{$name} = shift; |
97 } | 74 } |
98 } | 75 } |
99 | 76 |
100 sub GetMainBlock { | |
101 $_[0]->template->blocks->{RENDER} || $_[0]->template; | |
102 } | |
103 | |
104 sub Render { | 77 sub Render { |
105 my ($this,$args) = @_; | 78 my ($this,$args) = @_; |
106 | 79 |
107 $args = {} unless ref $args eq 'HASH'; | 80 $args = {} unless ref $args eq 'HASH'; |
108 | 81 |
109 if(my $body = $this->GetMainBlock ) { | 82 return $this->context->include( |
110 return $this->context->include( $body, { %$args, this => $this, template => $this->template } ); | 83 $this->template, |
111 } else { | 84 { |
112 return ""; | 85 %$args, |
113 } | 86 this => $this, |
114 } | 87 template => $this->template |
115 | 88 } |
116 sub RenderBlock { | 89 ); |
117 my ($this, $block, $args) = @_; | |
118 | |
119 $args = {} unless ref $args eq 'HASH'; | |
120 | |
121 return $block ? $this->context->include( $block, { %$args, this => $this, template => $this->template } ) : undef; | |
122 } | |
123 | |
124 sub ExportBlock { | |
125 my ($this,$block) = @_; | |
126 | |
127 return TemplateDocument->new({ | |
128 BLOCK => $this->template->blocks->{$block}, | |
129 DEFBLOCKS => $this->template->blocks | |
130 }); | |
131 } | 90 } |
132 | 91 |
133 sub AUTOLOAD { | 92 sub AUTOLOAD { |
134 our $AUTOLOAD; | 93 our $AUTOLOAD; |
135 | 94 |
164 | 123 |
165 [% | 124 [% |
166 META version = 1; | 125 META version = 1; |
167 BLOCK INIT; | 126 BLOCK INIT; |
168 # this is a document scope | 127 # this is a document scope |
169 dojo.require.push( 'dijit/form/Input' ); | 128 dojo.modules.push( 'dijit/form/Input' ); |
170 END; | 129 END; |
171 BLOCK CTOR; | 130 |
172 # local to this block | 131 # local to this block |
173 TPreview = require('My/Org/TextPreview'); | 132 TPreview = require('My/Org/TextPreview'); |
174 | 133 |
175 # init control props | 134 # init control props |
176 this.dojoClass = this.dojoClass || 'dijit.form.Input'; | 135 visualClass = this.visualClass || 'classic'; |
177 this.visualClass = this.visualClass || 'classic'; | 136 %] |
178 this.childNodes = []; | 137 <div id="$id" class="$visualClass" data-dojo-type="dijit/form/Input"> |
179 | 138 [% FOREACH item IN model %] |
180 # init content | 139 <div class="itemContainer"> |
181 FOREACH text IN this.data; | 140 [% Display(item) %] |
182 this.childNodes.push( TPreview.new('preview', nodeValue = text ) ); | 141 </div> |
183 END; | |
184 | |
185 END; | |
186 %] | |
187 | |
188 <div class="$this.visualClass" data-dojo-type="$this.dojoClass"> | |
189 [% FOREACH node IN this.childNodes %] | |
190 [% node.Render() %] | |
191 <hr /> | |
192 [% END %] | 142 [% END %] |
193 </div> | 143 </div> |
194 | 144 |
195 =end text | 145 =end text |
196 | 146 |
197 =head1 DESCRIPTION | 147 =head1 DESCRIPTION |
198 | 148 |
199 Представляет собой фрагмент документа, который имеет шаблон для отображения, | 149 Легкая обертка вокруг шаблона, позволяет изолировать пространство имен шаблона, |
200 набор свойств и т.п. | 150 а также реализовать собственные методы по представлению данных (в случае если |
151 это проще сделать в виде методов класса). | |
201 | 152 |
202 =head2 BLOCKS | 153 =head2 BLOCKS |
203 | 154 |
204 =head3 META | 155 =head3 META |
205 | 156 |