Next steps for testing will be to create an environment around the staff
client code so we can write some real tests...
+2013-12-02 Scopes, Services, and Routing
+----------------------------------------
+
+If you have two routes like so,
+
+[source,js]
+-----------------------------------------------------------------------------
+$routeProvider.when('/circ/patron/1/items_out', {...});
+$routeProvider.when('/circ/patron/1/holds', {...});
+-----------------------------------------------------------------------------
+
+You can access these two pages by changing your browser's URL or you can
+use links/actions in the page to jump between routes using pushstate
+routing.
+
+Pushsate routing allows you to change the browser URL and have the JS
+code respond to the change without actually reloading the web page. In
+short, it makes page switching faster. It does this in two main ways.
+
+1. The browser does not have to fetch the page and scripts from the
+server (or cache) or re-parse and execute scripts that run at page load
+time.
+
+2. If two pages share data, which is common for route-linked pages, then
+it's possible for the second page to access data retrieved by the first,
+without having to re-fetch it from the server.
+
+How do we manage routing and caching with angular scopes and services?
+
+Any time a path is loaded in Angular, regardless of how the path was
+accessed (routing or initial page load), all controllers within the page
+are re-initialized with an empty $scope. Naturally, this means that any
+data that was loaded into a $scope will no longer be available when the
+next route is accessed.
+
+To persist data across routes, it has to be managed outside of the
+controller. The Angular solution is to use a service. Generally
+speaking, Angular services provide re-usable chunks of logic that are
+scope and controller-agnostic. They are factory classes which produce
+singleton objects, instantiated once at page load, and persisted through
+all routes. Because of this, they double as a great place to store
+route-global data (i.e. data that should be cached between all of our
+known routes).
+
+Some examples, with lots of extra stuff left out:
+
+[source,js]
+-----------------------------------------------------------------------------
+.controller('PatronItemsOut', function($scope) {
+ fetchPatronFromServer(id).then(
+ function(p) { $scope.patron = p });
+})
+
+.controller('PatronHolds', function($scope) {
+ fetchPatronFromServer(id).then(
+ function(p) { $scope.patron = p });
+})
+-----------------------------------------------------------------------------
+
+Here we fetch the patron object from the server every time the
+PatronItemsOut or PatronHolds controllers are instantiated. Since
+these two controllers are managed within the same angular app, they are
+accessible via routing and can theoretically share date. Fetching the
+user every time is wasteful.
+
+Here's an example where we mange user retrieval with a service.
+
+[source,js]
+-----------------------------------------------------------------------------
+.factory('patronService', function() {
+ var service = {
+ // only cache the last-accessed user.
+ // caching all accessed users is a recipe for memory leaks
+ current : null
+ };
+ service.fetchPatron = function(id) {
+ // on initial page load, service.current will be null
+ if (service.current && service.current.id() == id) {
+ // no need to fetch!
+ } else {
+ // fetch patron and set service.current = patron
+ }
+ }
+ return service;
+})
+
+.controller('PatronItemsOut', function($scope, patronService) {
+ patronService.fetchPatron(id)
+ $scope.patron = function() { return patronService.current }
+})
+
+.controller('PatronHolds', function($scope, patronService) {
+ patronService.fetchPatron(id)
+ $scope.patron = function() { return patronService.current }
+})
+-----------------------------------------------------------------------------
+
+Now the patron object lives within our patronService Angular service. It
+will persist through page routes until we replace the value or reload
+the page. Note that we are now accessing our patron at $scope.patron()
+instead of $scope.patron, because $scope.patron() is guaranteed to always
+return the correct value for the current patron. Angular templates are
+perfectly happy to work with functions intead of attributes.
+
+[source,html]
+-----------------------------------------------------------------------------
+<div>Username: {{patron().usrname()}}</div>
+-----------------------------------------------------------------------------
+
+
Future Topics...
----------------
+ * My (currently) preferred parent scope, child scope, service pattern
+ * Promises
* Routing vs Loading
* Angular Services / _Route Persistence_
* Deep Linking / Managing the _first load_ problem