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