move viewport to being %_ arg only, not widget attribute, cache widget construction
matthewt [Thu, 15 Nov 2007 21:12:16 +0000 (21:12 +0000)]
lib/Reaction/UI/View.pm
lib/Reaction/UI/Widget.pm
lib/Reaction/UI/Widget/Field.pm
lib/Reaction/UI/Widget/ListView.pm

index 92aa7c5..8f0c265 100644 (file)
@@ -10,6 +10,7 @@ class View which {
 
   has '_layout_set_cache'   => (is => 'ro', default => sub { {} });
   has '_widget_class_cache' => (is => 'ro', default => sub { {} });
+  has '_widget_cache' => (is => 'ro', default => sub { {} });
 
   has 'app' => (is => 'ro', required => 1);
 
@@ -54,15 +55,17 @@ class View which {
     my ($self, $rctx, $vp) = @_;
     my $layout_set = $self->layout_set_for($vp);
     my $widget = $self->widget_for($vp, $layout_set);
-    $widget->render($rctx);
+    $widget->render($rctx, { viewport => $vp });
   };
 
   implements 'widget_for' => as {
     my ($self, $vp, $layout_set) = @_;
-    return $self->widget_class_for($layout_set)
-                ->new(
-                    view => $self, viewport => $vp, layout_set => $layout_set
-                  );
+    return
+      $self->_widget_cache->{$layout_set->name}
+        ||= $self->widget_class_for($layout_set)
+                 ->new(
+                     view => $self, layout_set => $layout_set
+                   );
   };
 
   implements 'widget_class_for' => as {
index c27e905..9c3c69e 100644 (file)
@@ -7,14 +7,12 @@ use aliased 'Reaction::UI::LayoutSet';
 
 class Widget which {
 
-  has 'viewport' => (isa => ViewPort, is => 'ro'); # required?
   has 'view' => (isa => View, is => 'ro', required => 1);
   has 'layout_set' => (isa => LayoutSet, is => 'ro', required => 1);
 
   implements 'render' => as {
-    my ($self, $rctx) = @_;
-    my $args = { self => $self };
-    $args->{viewport} = $self->viewport if $self->has_viewport;
+    my ($self, $rctx, $passed_args) = @_;
+    my $args = { self => $self, %$passed_args };
     $self->render_widget($rctx, $args);
   };
 
index 13276c2..40ca595 100644 (file)
@@ -4,15 +4,9 @@ use Reaction::UI::WidgetClass;
 
 class Field, which {
 
-  has id   => (isa => 'Str', is => 'ro', lazy_build => 1);
-  has name => (isa => 'Str', is => 'ro', lazy_build => 1);
-
-  implements _build_id   => as { shift->viewport->event_id_for('value'); };
-  implements _build_name => as { shift->viewport->event_id_for('value'); };
-
   fragment widget [qw/label field message/
-                  => { id       => func('self', 'id'),
-                       name     => func('self', 'name'), }
+                  => { id       => sub { $_{viewport}->event_id_for('value') },
+                       name     => sub { $_{viewport}->event_id_for('value') },
                  ];
 
   fragment field   [ string { $_{viewport}->value },   ];
index 47e65a5..81b652e 100644 (file)
@@ -24,23 +24,23 @@ class ListView is 'Reaction::UI::Widget::GridView', which {
     ];
 
   fragment first_page    [ string{ "First" } ],
-    { uri => sub{ $_{self}->connect_uri( {page => $_{first_page} } )    } };
+    { uri => sub{ $_{self}->connect_uri( {page => $_{first_page} }, $_{viewport} )    } };
 
   fragment previous_page [ string{ "Previous" } ],
-    { uri => sub{ $_{self}->connect_uri( {page => $_{previous_page} } ) } };
+    { uri => sub{ $_{self}->connect_uri( {page => $_{previous_page} }, $_{viewport} ) } };
 
   fragment current_page  [ string{ "Current" } ],
-    { uri => sub{ $_{self}->connect_uri( {page => $_{current_page} } )  } };
+    { uri => sub{ $_{self}->connect_uri( {page => $_{current_page} }, $_{viewport} )  } };
 
   fragment next_page     [ string{ "Next" } ],
-    { uri => sub{ $_{self}->connect_uri( {page => $_{next_page} } )     } };
+    { uri => sub{ $_{self}->connect_uri( {page => $_{next_page} }, $_{viewport} )     } };
 
   fragment last_page     [ string{ "Last" } ],
-    { uri => sub{ $_{self}->connect_uri( {page => $_{last_page} } )     } };
+    { uri => sub{ $_{self}->connect_uri( {page => $_{last_page} }, $_{viewport} )     } };
 
   fragment page_list [ page => over $_{page_list} ];
   fragment page      [ string{ $_ } ],
-    { uri => sub{ $_{self}->connect_uri( {page => $_ } ) } };
+    { uri => sub{ $_{self}->connect_uri( {page => $_ }, $_{viewport} ) } };
 
   fragment actions [ action => over func(viewport => 'actions') ];
   fragment action  [ 'viewport' ];
@@ -48,22 +48,21 @@ class ListView is 'Reaction::UI::Widget::GridView', which {
   fragment header_cell [ string { $_{labels}->{$_} } ],
     { uri => sub{
         my $ev = {order_by => $_, order_by_desc => $_{viewport}->order_by_desc ? 0 : 1 };
-        return $_{self}->connect_uri($ev);
+        return $_{self}->connect_uri($ev, $_{viewport});
       }
     };
 
   fragment footer_cell [ string { $_{labels}->{$_} } ],
     { uri => sub{
         my $ev = {order_by => $_, order_by_desc => $_{viewport}->order_by_desc ? 0 : 1 };
-        return $_{self}->connect_uri($ev);
+        return $_{self}->connect_uri($ev, $_{viewport});
       }
     };
 
   #this needs to be cleaned up and moved out
   implements connect_uri => as{
-    my ($self, $events) = @_;
-    my $vp   = $self->viewport;
-    my $ctx  = $self->viewport->ctx;
+    my ($self, $events, $vp) = @_;
+    my $ctx  = $vp->ctx;
     my %args = map{ $vp->event_id_for($_) => $events->{$_} } keys %$events;
     return $ctx->req->uri_with(\%args);
   };