Filtering with ListModels and ListPresenters

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Filtering with ListModels and ListPresenters

Andrew Lawson
Hello

I quite often find myself with a model being or holding an
OrderedCollection or similar and wanting to display this, but with the
need to filter down the objects displayed. Until now I've simply had and
changes to the model collection trigger a method in the main presenter
which filled a presenter-hosted collection via a filter and used this as
the model for the ListPresenter. This now strikes me as an overly
complicated way of doing things and I'm searching for a simple solution.
Initially I was thinking about writing a FilteredListPresenter but
looking at the code I can't see any easy way to influence the collection
items visible to the view. So I'm left with two options; write a
FilteredListModel, overriding every read-accessor to return a collection
having been selected with a supplied filterBlock or do something similar
with a ListView, although this may require repeating the exercise for
all the different types of view I may be using. Has anyone done
something similar, have code available or simply have an idea?

    thanks

        Andrew

--
  ...................................
  .          Andrew Lawson          .
  . (reverse "moc.sitnesba@werdna") .
  .     http://www.absentis.com     .
  ...................................

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----


Reply | Threaded
Open this post in threaded view
|

Re: Filtering with ListModels and ListPresenters

Chris Uppal-3
Andrew Lawson wrote:

> Initially I was thinking about writing a FilteredListPresenter but
> looking at the code I can't see any easy way to influence the collection
> items visible to the view. So I'm left with two options; write a
> FilteredListModel, overriding every read-accessor to return a collection
> having been selected with a supplied filterBlock or do something similar
> with a ListView, although this may require repeating the exercise for
> all the different types of view I may be using. Has anyone done
> something similar, have code available or simply have an idea?

I did something similar with a custom ListModel.  It's based on some
discussions we've had here in this group (sorry, but I can't be bothered to
look for the references ;-)  In essence it's a ListModel that provides a
filtered and sortable "view" (in the database sense) of another ListModel.
Changes to the underlying ListModel are reflected in the derived model.

I was planning to add it to my website when I next update that, but that's not
likely to happen too soon (unfortunately), so I've put a temporary link to it
at
    http://ephemera.metagnostic.org/code/DML.zip
in case you or anyone else want to take a look at it.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Filtering with ListModels and ListPresenters

Andrew Lawson
"Chris Uppal" <[hidden email]> writes:
> I was planning to add it to my website when I next update that, but
> that's not likely to happen too soon (unfortunately), so I've put a
> temporary link to it at http://ephemera.metagnostic.org/code/DML.zip
> in case you or anyone else want to take a look at it.

Perfect, this is exactly what I was looking for, thanks very much. At
first use it works perfectly, 1 question: The class comment seems to say
that usage is;

DerivedListPresenter model: (DerivedListModel on: (ListModel on:
aCollection))

Is there any reason for the extra (ListModel) level of indirection?

    thanks

        Andrew

--
  ...................................
  .          Andrew Lawson          .
  . (reverse "moc.sitnesba@werdna") .
  .     http://www.absentis.com     .
  ...................................

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----


Reply | Threaded
Open this post in threaded view
|

Re: Filtering with ListModels and ListPresenters

Chris Uppal-3
Andrew Lawson wrote:

> The class comment seems to say
> that usage is;
>
> DerivedListPresenter model: (DerivedListModel on: (ListModel on:
> aCollection))
>
> Is there any reason for the extra (ListModel) level of indirection?

Probably the best way to explain is to give an example of how it's designed to
be used.

Consider the venerable example of a Library containing Books.  The Library and
the Books are part of the domain (as opposed to the presentation layer), and
the Library must (somehow) expose its collection of books to GUI code, and
ensure that the GUI can keep up-to-date with any changes to the list.  There
are various approaches to doing that, one of the simplest is for it to contain
a ListModel of Books, which it exposes.  GUI code can then connect a
ListPresenter to that ListModel and the presentation will then track any
changes automatically.

The problem with that is that the ListModel is part of the domain, but is being
used as part of the presentation.  That is a bit iffy IMO, from a design POV.
One concrete problem it causes is that if a user sorts the list in the GUI then
the list /in the model/ will be sorted.  A similar problem is that going from a
straight presentation of the entire list of books to a filtered selection of
them requires completely different code -- and besides being a nuisance, I
think that discontinuity is a symptom of a poorly arranged design.

The idea of DerivedListModel is to allow a better separation of domain and
presentation code without requiring a load of extra hand-written event
handling.  In this example, the Library can contain a ListModel, which it
allows the GUI code to "see" (just as before), but the GUI code does not use
that object directly in MVP components.  Instead it attaches one or more
DerivedListModels to it, and uses those in the presentation.  Thus the lists
that the user sees will all continue to update automatically as the underlying
(domain) model changes, but user can also choose to sort those lists in
different orders, or apply filters to each independently.

The reason that the domain (Library) has to contain a ListModel rather than
just an OrderedCollection of Books, is that otherwise there will be no
automatic notification of changes.  If you don't want, or need, automatic
updates, then there's very little point to an object like a DerivedListModel,
since you might just as well take a copy of the list in the model whenever you
need to -- which is very simple to code.
    books := self model books select: self bookFilter.
    (self presenterNamed: 'Book List') list: books.

Of course, there are several viable approaches to solving these design
problems.  DerivedListModel is merely an attempt to pre-package one of them.

    -- chris