Permalink
Browse files

updated library example

  • Loading branch information...
1 parent 84ca6c0 commit b3340c7f240d4f4fcbf5534a1f9e6c131aa4e2b4 @seanhess committed May 2, 2009
View
94 examples/Library/src/books/control/Browse.as
@@ -1,94 +0,0 @@
-package books.control
-{
- import books.adapt.AuthorBooks;
- import books.model.Author;
- import books.model.Book;
- import books.model.NavHistoryItem;
-
- import flash.events.EventDispatcher;
-
- import mx.collections.IList;
-
- [Bindable]
- public class Browse extends EventDispatcher
- {
- public var books:IList;
-
- public var currentAuthor:Author;
- public var currentBook:Book;
-
- private var history:Array = [];
-
- public var backEnabled:Boolean = false;
-
- public function showAuthor(value:Author):void
- {
- var authorBooks:AuthorBooks = new AuthorBooks();
- authorBooks.author = value;
- authorBooks.books = books;
-
- value.books = authorBooks;
- currentAuthor = value;
-
- addHistoryItem(currentAuthor);
-
- dispatchEvent(new Event("showAuthor"));
- }
-
- public function showBook(value:Book):void
- {
- currentBook = value;
- addHistoryItem(currentBook);
- dispatchEvent(new Event("showBook"));
- }
-
- public function goBack():void
- {
- restoreHistoryItem();
- dispatchEvent(new Event("goBack"));
- }
-
- public function showSearch():void
- {
- resetHistory();
- dispatchEvent(new Event("showSearch"));
- }
-
- public function showBrowse():void
- {
- resetHistory();
- dispatchEvent(new Event("showBrowse"));
- }
-
- public function addHistoryItem(value:*):void
- {
- var item:NavHistoryItem = new NavHistoryItem();
- item.type = (value is Book) ? NavHistoryItem.BOOK : NavHistoryItem.AUTHOR;
- item.book = value as Book;
- item.author = value as Author;
-
- history.push(item);
- backEnabled = (history.length > 0);
- }
-
- public function restoreHistoryItem():void
- {
- history.pop(); // just ditch the last one
-
- if (history.length > 0)
- {
- var item:NavHistoryItem = history[history.length-1];
- currentBook = item.book;
- currentAuthor = item.author;
- }
-
- backEnabled = (history.length > 0);
- }
-
- public function resetHistory():void
- {
- history = new Array();
- backEnabled = false;
- }
- }
-}
View
109 examples/Library/src/books/control/MainGlue.mxml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Controller xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://glue.seanhess.net/2009" xmlns:control="books.control.*" xmlns:view="books.view.*" xmlns:browse="books.view.browse.*" xmlns:pages="books.view.pages.*" xmlns:model="books.model.*">
+<Controller xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="http://glue.seanhess.net/2009" xmlns:control="books.control.*" xmlns:view="books.view.*" xmlns:browse="books.view.browse.*" xmlns:pages="books.view.pages.*" xmlns:model="books.model.*" xmlns:service="books.service.*">
<mx:Script>
<![CDATA[
@@ -8,98 +8,27 @@
]]>
</mx:Script>
+ <!-- MODELS -->
<model:Library id="library"/>
-
- <Glue>
- <control:Browse id="browse"/>
- <Inject books="{library.books}"/>
- </Glue>
-
- <Glue>
- <control:Search id="search"/>
- <Inject
- allBooks="{library.books}"
- allAuthors="{library.authors}"
- />
- </Glue>
-
-
-
-
-
-
-
-
+ <model:Browse id="browse"/>
+ <model:Search id="search"/>
+ <!-- SERVICES -->
+ <service:BrowseService id="browseService" browse="{browse}" library="{library}"/>
+ <service:SearchService id="searchService" search="{search}" library="{library}"/>
+
+
+
+
- <!--
- VIEWS
-
- There should normally be one Glue for each view you care about.
- It will glue every view of that type, so if you use a component,
- instead of a view, all of them will get the same glue.
-
- The View is declared as the first child of the glue. If you do
- this, it throws the one you create away, and replaces it with the
- currently matched view. It sets the selector's match property to
- the classname of the view for you. In other words, this is some
- magic to get you autocompletion, but the instance you are working
- on will always be replaced with the right one (if you follow
- conventions).
-
- If you want to target a specific instance of a component, you
- can use Bifff's selectors (bifff.seanhess.net). For example, you
- could say <Glue match="ResultsPage#main"> and it would target the
- results page with an id of main.
-
- BEST PRACTICE: Only specify injections and observes that set or
- call something on the view in question. Views should never target
- other views. The target property is to say which controller to
- listen to, or to drill into an unencapsulated view.
-
-
-
- ================================================================
-
- MainView
-
- I am using it's creation complete to initialize the app
- MainView has some encapsulated events, so we'll use the constants
- instead of typing the event names.
-
- ==================================================================
-
- MainPagesView
-
- Notice how I am reusing the ResultsPage component and injecting
- different results into both browse and search
-
- You can encapsulate views as much as you want. If you don't,
- you can reach into them using the target attribute, like I've
- done with back, browseResults and searchResults.
-
- I set up observe tags to listen to the view (like the back
- click handler), and to respond to a controller action
- in the view. The second usage makes it so I can call the
- controller from anywhere, and this view will get updated.
-
- It should be considered bad practice to target another view
- with an observe tag. Any injector target should be something
- inside the view.
-
- Play around with it. Notice the auto-complete!
-
- Inject will throw a runtime error if the target doesn't
- have the runtime property it is trying to inject to.
- -->
<Glue>
<view:MainView id="mainView"/>
<Route event="{FlexEvent.CREATION_COMPLETE}" call="library.mock()"/>
- <Route event="{MainView.SEARCH}" call="browse.showSearch()"/>
- <Route event="{MainView.BROWSE}" call="browse.showBrowse()"/>
+ <Route event="{MainView.SEARCH}" call="browseService.showSearch()"/>
+ <Route event="{MainView.BROWSE}" call="browseService.showBrowse()"/>
</Glue>
<Glue>
@@ -109,7 +38,7 @@
<Inject child="{pages.browseResults}" books="{library.books}" authors="{library.authors}"/>
<Inject child="{pages.searchResults}" books="{search.bookResults}" authors="{search.authorResults}"/>
- <Route child="{pages.back}" event="click" call="browse.goBack()"/>
+ <Route child="{pages.back}" event="click" call="browseService.goBack()"/>
<Observe model="{browse}" event="goBack" call="pages.goBack()"/>
<Observe model="{browse}" event="showSearch" call="pages.showSearch()"/>
@@ -122,8 +51,8 @@
<Glue>
<pages:ResultsPage id="results"/>
- <Route event="{ResultsPage.SELECT_BOOK}" call="browse.showBook(results.selectedBook)"/>
- <Route event="{ResultsPage.SELECT_AUTHOR}" call="browse.showAuthor(results.selectedAuthor)"/>
+ <Route event="{ResultsPage.SELECT_BOOK}" call="browseService.showBook(results.selectedBook)"/>
+ <Route event="{ResultsPage.SELECT_AUTHOR}" call="browseService.showAuthor(results.selectedAuthor)"/>
</Glue>
<!--
@@ -132,18 +61,18 @@
<Glue>
<pages:BookPage id="bookView"/>
<Inject book="{browse.currentBook}"/>
- <Route child="{bookView.authorButton}" event="click" call="browse.showAuthor(bookView.book.author)"/>
+ <Route child="{bookView.authorButton}" event="click" call="browseService.showAuthor(bookView.book.author)"/>
</Glue>
<Glue>
<pages:AuthorPage id="authorView"/>
<Inject author="{browse.currentAuthor}"/>
- <Route child="{authorView.booksList}" event="itemClick" call="browse.showBook(authorView.booksList.selectedItem as Book)"/>
+ <Route child="{authorView.booksList}" event="itemClick" call="browseService.showBook(authorView.booksList.selectedItem as Book)"/>
</Glue>
<Glue>
<pages:SearchPage id="searchView"/>
- <Route child="{searchView.searchBtn}" event="click" call="search.search(searchView.input.text)"/>
+ <Route child="{searchView.searchBtn}" event="click" call="searchService.doSearch(searchView.input.text)"/>
</Glue>
</Controller>
View
53 examples/Library/src/books/control/Search.as
@@ -1,53 +0,0 @@
-package books.control
-{
- import books.model.Author;
- import books.model.Book;
-
- import flash.events.Event;
- import flash.events.EventDispatcher;
-
- import mx.collections.IList;
- import mx.collections.ListCollectionView;
-
- [Bindable]
- public class Search extends EventDispatcher
- {
- public var authorResults:IList;
- public var bookResults:IList;
-
- public var allAuthors:IList;
- public var allBooks:IList;
-
- private var searchTerm:String;
-
- /**
- * For now, just do an exact regex match on any part of the name or title
- */
- public function search(term:String):void
- {
- searchTerm = term;
-
- var authors:ListCollectionView = new ListCollectionView(allAuthors);
- authors.filterFunction = searchAuthor;
- authors.refresh();
-
- var books:ListCollectionView = new ListCollectionView(allBooks);
- books.filterFunction = searchBook;
- books.refresh();
-
- authorResults = authors;
- bookResults = books;
- dispatchEvent(new Event('search'));
- }
-
- private function searchAuthor(author:Author):Boolean
- {
- return author.name.match(searchTerm) != null;
- }
-
- private function searchBook(book:Book):Boolean
- {
- return book.title.match(searchTerm) != null;
- }
- }
-}
View
50 examples/Library/src/books/model/Browse.as
@@ -0,0 +1,50 @@
+package books.model
+{
+ import books.model.Author;
+ import books.model.Book;
+ import books.model.NavHistoryItem;
+
+ import flash.events.EventDispatcher;
+
+ [Bindable]
+ public class Browse extends EventDispatcher
+ {
+ public var currentAuthor:Author;
+ public var currentBook:Book;
+
+ public var history:Array = [];
+
+ public var backEnabled:Boolean = false;
+
+ public function showAuthor():void
+ {
+ dispatchEvent(new Event("showAuthor"));
+ }
+
+ public function showBook():void
+ {
+ dispatchEvent(new Event("showBook"));
+ }
+
+ public function goBack():void
+ {
+ dispatchEvent(new Event("goBack"));
+ }
+
+ public function showSearch():void
+ {
+ dispatchEvent(new Event("showSearch"));
+ }
+
+ public function showBrowse():void
+ {
+ dispatchEvent(new Event("showBrowse"));
+ }
+
+ public function addHistoryItem(item:NavHistoryItem):void
+ {
+ history.push(item);
+ }
+
+ }
+}
View
25 examples/Library/src/books/model/Search.as
@@ -0,0 +1,25 @@
+package books.model
+{
+ import books.model.Author;
+ import books.model.Book;
+
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+
+ import mx.collections.IList;
+ import mx.collections.ListCollectionView;
+
+ [Bindable]
+ public class Search extends EventDispatcher
+ {
+ public var authorResults:IList;
+ public var bookResults:IList;
+
+ public var searchTerm:String;
+
+ public function search():void
+ {
+ dispatchEvent(new Event("search"));
+ }
+ }
+}
View
85 examples/Library/src/books/service/BrowseService.as
@@ -0,0 +1,85 @@
+package books.service
+{
+ import books.adapt.AuthorBooks;
+ import books.model.Author;
+ import books.model.Book;
+ import books.model.Browse;
+ import books.model.Library;
+ import books.model.NavHistoryItem;
+
+ public class BrowseService
+ {
+ public var browse:Browse;
+ public var library:Library;
+
+ public function showAuthor(value:Author):void
+ {
+ var authorBooks:AuthorBooks = new AuthorBooks();
+ authorBooks.author = value;
+ authorBooks.books = library.books;
+
+ value.books = authorBooks;
+ browse.currentAuthor = value;
+
+ addHistoryItem(browse.currentAuthor);
+ browse.showAuthor();
+ }
+
+ public function showBook(value:Book):void
+ {
+ browse.currentBook = value;
+ addHistoryItem(value);
+ browse.showBook();
+ }
+
+ public function goBack():void
+ {
+ restoreHistoryItem();
+ browse.goBack();
+ }
+
+ public function showSearch():void
+ {
+ resetHistory();
+ browse.showSearch();
+ }
+
+ public function showBrowse():void
+ {
+ resetHistory();
+ browse.showBrowse();
+ }
+
+ public function addHistoryItem(value:*):void
+ {
+ var item:NavHistoryItem = new NavHistoryItem();
+ item.type = (value is Book) ? NavHistoryItem.BOOK : NavHistoryItem.AUTHOR;
+ item.book = value as Book;
+ item.author = value as Author;
+
+ browse.addHistoryItem(item);
+ browse.backEnabled = (browse.history.length > 0);
+ }
+
+ public function restoreHistoryItem():void
+ {
+ browse.history.pop(); // just ditch the last one
+
+ if (browse.history.length > 0)
+ {
+ var item:NavHistoryItem = browse.history[browse.history.length-1];
+ browse.currentBook = item.book;
+ browse.currentAuthor = item.author;
+ }
+
+ browse.backEnabled = (browse.history.length > 0);
+ }
+
+ public function resetHistory():void
+ {
+ browse.history = new Array();
+ browse.backEnabled = false;
+ }
+
+ }
+}
View
46 examples/Library/src/books/service/SearchService.as
@@ -0,0 +1,46 @@
+package books.service
+{
+ import books.model.Author;
+ import books.model.Book;
+ import books.model.Library;
+ import books.model.Search;
+
+ import mx.collections.ListCollectionView;
+
+ public class SearchService
+ {
+ public var library:Library;
+ public var search:Search;
+
+ /**
+ * For now, just do an exact regex match on any part of the name or title
+ */
+ public function doSearch(term:String):void
+ {
+ search.searchTerm = term;
+
+ var authors:ListCollectionView = new ListCollectionView(library.authors);
+ authors.filterFunction = searchAuthor;
+ authors.refresh();
+
+ var books:ListCollectionView = new ListCollectionView(library.books);
+ books.filterFunction = searchBook;
+ books.refresh();
+
+ search.authorResults = authors;
+ search.bookResults = books;
+ search.search();
+ }
+
+ private function searchAuthor(author:Author):Boolean
+ {
+ return author.name.match(search.searchTerm) != null;
+ }
+
+ private function searchBook(book:Book):Boolean
+ {
+ return book.title.match(search.searchTerm) != null;
+ }
+
+ }
+}

0 comments on commit b3340c7

Please sign in to comment.