Commit | Line | Data |
ddccc6a2 |
1 | package Reaction::UI::ViewPort::Collection; |
2 | |
3 | use Reaction::Class; |
4 | use Scalar::Util qw/blessed/; |
5 | use aliased 'Reaction::InterfaceModel::Collection' => 'IM_Collection'; |
6 | use aliased 'Reaction::UI::ViewPort::Object'; |
7 | |
7b5e71ad |
8 | use MooseX::Types::Moose qw/Str HashRef/; |
9 | |
81393881 |
10 | use namespace::clean -except => [ qw(meta) ]; |
11 | extends 'Reaction::UI::ViewPort'; |
ddccc6a2 |
12 | |
d738d11f |
13 | with 'Reaction::UI::ViewPort::Collection::Role::Pager'; |
14 | with 'Reaction::UI::ViewPort::Role::Actions'; |
15 | |
81393881 |
16 | has members => (is => 'rw', isa => 'ArrayRef', lazy_build => 1); |
17 | |
18 | has collection => (is => 'ro', isa => IM_Collection, required => 1); |
19 | has current_collection => (is => 'rw', isa => IM_Collection, lazy_build => 1); |
20 | |
7b5e71ad |
21 | has member_args => ( is => 'rw', isa => HashRef, lazy_build => 1); |
22 | has member_class => ( is => 'ro', isa => Str, lazy_build => 1); |
f46fa4fd |
23 | |
81393881 |
24 | sub BUILD { |
25 | my ($self, $args) = @_; |
26 | if( my $member_args = delete $args->{Member} ){ |
27 | $self->member_args( $member_args ); |
28 | } |
f46fa4fd |
29 | } |
30 | |
31 | sub _build_member_args { {} } |
32 | |
81393881 |
33 | sub _build_member_class { Object }; |
34 | |
35 | after clear_current_collection => sub{ |
36 | shift->clear_members; #clear the members the current collection changes, duh |
ddccc6a2 |
37 | }; |
f46fa4fd |
38 | |
81393881 |
39 | sub _build_current_collection { |
40 | return $_[0]->collection; |
f46fa4fd |
41 | } |
81393881 |
42 | |
43 | #I'm not really sure why this is here all of a sudden. |
f46fa4fd |
44 | sub model { shift->current_collection } |
45 | |
81393881 |
46 | sub _build_members { |
47 | my ($self) = @_; |
48 | my (@members, $i); |
49 | my $args = $self->member_args; |
50 | my $builders = {}; |
f46fa4fd |
51 | my $field_orders = {}; |
81393881 |
52 | my $ctx = $self->ctx; |
53 | my $loc = join('-', $self->location, 'member'); |
54 | my $class = $self->member_class; |
55 | |
56 | #replace $i with a real unique identifier so that we don't run a risk of |
57 | # events being passed down to the wrong viewport. for now i disabled event |
58 | # passing until i fix this (groditi) |
59 | for my $obj ( $self->current_collection->members ) { |
60 | my $type = blessed $obj; |
61 | my $builder_cache = $builders->{$type} ||= {}; |
f46fa4fd |
62 | my @order; |
63 | if( exists $args->{computed_field_order} ){ |
64 | @order = (computed_field_order => $args->{computed_field_order}); |
65 | } elsif( exists $field_orders->{$type} ) { |
66 | @order = (computed_field_order => $field_orders->{$type}); |
67 | } |
68 | |
81393881 |
69 | my $member = $class->new( |
f46fa4fd |
70 | ctx => $ctx, |
71 | model => $obj, |
72 | location => join('-', $loc, $i++), |
73 | builder_cache => $builder_cache, |
74 | @order, %$args, |
75 | ); |
76 | |
77 | #cache to prevent the sort function from having to be run potentially |
78 | #hundreds of times |
79 | $field_orders->{$type} ||= $member->computed_field_order unless @order; |
81393881 |
80 | push(@members, $member); |
81 | } |
82 | return \@members; |
83 | }; |
84 | |
85 | __PACKAGE__->meta->make_immutable; |
86 | |
ddccc6a2 |
87 | |
2dba7201 |
88 | 1; |
ddccc6a2 |
89 | |
2dba7201 |
90 | __END__; |
ddccc6a2 |
91 | |
2dba7201 |
92 | =head1 NAME |
93 | |
94 | Reaction::UI::ViewPort::Collection |
95 | |
96 | =head1 DESCRIPTION |
97 | |
7460b544 |
98 | Creates, from an InterfaceModel::Collection, a list of viewports representing |
99 | each member of the collection. |
2dba7201 |
100 | |
101 | =head1 ATTRIBUTES |
102 | |
103 | =head2 collection |
104 | |
7460b544 |
105 | Required read-only L<InterfaceModel::Collection|Reaction::InterfaceModel::Collection> |
106 | This is the original collection. |
107 | |
2dba7201 |
108 | =head2 current_collection |
109 | |
7460b544 |
110 | Read-only, lazy-building |
111 | L<InterfaceModel::Collection|Reaction::InterfaceModel::Collection> |
112 | This is the collection that will be used to create C<members> and should be |
113 | altered to reflect any ordering, paging, etc. By default this is the |
114 | same thing as C<collection>. |
115 | |
2dba7201 |
116 | =head2 member_args |
117 | |
7460b544 |
118 | A read-write HASH ref of additional parameters to pass to the C<member_class> |
119 | constructor as items are instantiated. |
120 | |
2dba7201 |
121 | =head2 member_class |
122 | |
7460b544 |
123 | The class to use when instantiating items to represent the member items. |
124 | |
125 | See: L<Object|Reaction::UI::ViewPort::Object>, |
d738d11f |
126 | L<Member|Reaction::UI::ViewPort::Collection::Grid::Member>. |
7460b544 |
127 | |
2dba7201 |
128 | =head1 INTERNAL METHODS |
129 | |
7460b544 |
130 | These methods, although stable, are subject to change without notice. |
131 | Extend at your own risk, APIs may change in the future. |
2dba7201 |
132 | |
133 | =head2 BUILD |
134 | |
7460b544 |
135 | Intercept a parameter with the key C<Member> amd store it in C<member_args> |
2dba7201 |
136 | |
137 | =head2 model |
138 | |
7460b544 |
139 | Returns the C<current_collection> |
140 | |
141 | =head2 _build_members |
142 | |
143 | Build individual viewports for each member of the collection, |
144 | |
145 | =head2 _build_member_args |
146 | |
147 | Defaults to an empty HASH ref. |
148 | |
149 | =head2 _build_member_class |
150 | |
151 | Defaults to L<Reaction::UI::ViewPort::Object> |
152 | |
2dba7201 |
153 | =head1 AUTHORS |
154 | |
155 | See L<Reaction::Class> for authors. |
156 | |
157 | =head1 LICENSE |
158 | |
159 | See L<Reaction::Class> for the license. |
160 | |
161 | =cut |