by ampatspell
in Code
Just got working the first prototype implementation of ListController for GWT (name comes from Cocoa NSArrayController).
Here is small screencast that shows List<BlogEntry> observation and “reaction” to element adds (ListController) and element property changes (Bindings). Video has no sound, better viewed full-screen.
ListController<T> takes content observable List<T> and observes ADD (later will also handle REMOVE, REPLACE, CLEAR) operations. When it happens, calls:
ListControllerTarget#create that should add the widget to the screenListControllerTarget#bind that should bind widget to model propertiesblogEntries.addDelegate(new ListControllerTarget<BlogEntry, BlogEntryListView>() { public BlogEntryListView create() { return view.addListEntry(); } public void bind(Bindings bindings, BlogEntry model, BlogEntryListView view) { // bind BlogEntry#title to HasText subject() bindings.bind(observable(model, "title", String.class), hasText(view.subject())); // bind BlogEntry#published to HasText marker() using boolean to marker text transformer // (which transforms true to "Published" and false to "Draft") bindings.bind(observable(model, "published", Boolean.class), hasText(view.marker()), new BooleanToMarkerTransformer()); } });
ObservableList<T> is an ArrayList<T> subclass which implements IsObservable and overrides add, remove mutators and notifies about element changes.
BlogEntry implements IsModel which extends IsObservable and also is observable.
Observation and Bindings are based on IsObservable ยป Observable:
BlogEntry entry = GWT.create(BlogEntry.class) // needs GWT generator ObserverRegistration reg = ((Observable) entry).getReflection().observe("title", String.class, new Observer<String>() { public void onValueChange(KeyPath keyPath, Operation operation, IndexSet indexes, String oldValue, String newValue) { // "title" value has changed } }); reg.remove(); // to remove observer when it is not needed anymore
Next: ListController selection, ObjectController, DataSource a la NSManagedObjectContext / SproutCode DataSource or something like that.