implementation was very route-centric: • Specify all QPs in the Router.map DSL • Optionally pass QP values to server queries • Optionally use QP values to set controller properties
are bound to controller properties: update controller QP prop and URL will update, and vice versa • No need for custom observing / coalescing of controller QP property changes
page: 1 // default value }); • When `page` === 1, URL is “/articles” • When `page` === 2, URL is “/articles?page=2” • If user clicks back button, intelligently deserialize into same type as default value; no need for parseInt, boolValue === “true”, etc
(with link-to and transitionTo) • Deeply nested templates • Loading / error substates • Action bubbling • …and a beautiful API to manage and reason about the above very challenging use cases
wrong ones) • Welcome to the Dismal Science of API Design • Goal: find the missing primitive, expose it as something that can be configured when necessary, but offer a high-level convention so that configuration is rare
today is coupled to controller lifecycle • Very convenient for the ArticlesController at /articles • Pretty undesirable / error-prone for the ArticlesShowController at /articles/some- title
vs /articles/some-title is that one has a uniquely identifiable model • Property stickiness for ArticlesController: desirable • Property stickiness for ArticlesShowController: only desirable when its model hasn’t changed • e.g. isSelected shouldn’t be preserved when switching b/w some-title and other-title articles
specific model • Store / restore controller properties scoped to the controller’s model • e.g. remember that article with ID ‘some-title’ isSelected, but ‘other-title’ is not
all controllers • Each sticky property is responsible for computing a bucket key • Replace sticky properties with bindings into the cache object, keyed by bucket key
properties; when they change, a new bucket is allocated (or a previous one is looked up) • Bucket keys based on the controller’s model ID give us… Model Dependent State
bucket is allocated • Could just be a POJO (memory cache, forgotten on page reload) • Could be your own LocalStorageProxy that writes into local storage as values change (remembered upon page reload)