Up tonight, a (hopefully) simple update of a Polymer feature.
Last night I was able to use attributes to set the initial toppings for a pizza in the
<x-pizza> Polymer-based custom element:
Today, I would like to do the opposite: ensure that topping changes are reflected in the same attributes that are used to set the initial toppings. That is, if an
<x-pizza> starts with:<x-pizza toppings="pepperoni,sausage"></x-pizza>And the user adds green peppers, then the attribute should report:
<x-pizza toppings="pepperoni,sausage,green peppers"></x-pizza>Mercifully, this is fairly easy in Polymer. It also helps that the infrastructure is already in place in the backing
x_pizza.dart backing class. The whole toppings attribute (toppings) and the first and second half attributes (toppings1 and toppings2) are already published in the backing class. I also have an updatePizzaState method that gets invoked whenever the model in my model driven view is updated:@CustomTag('x-pizza')
class XPizza extends PolymerElement {
// ...
@published String toppings = '';
@published String toppings1 = '';
@published String toppings2 = '';
XPizza.created(): super.created() {
model = new Pizza()
..changes.listen(updatePizzaState);
// ...
}
// ...
}The above changes stream just works because the model class has all the observables in place:class Pizza extends Observable {
ObservableList<String> firstHalfToppings = toObservable([]);
ObservableList<String> secondHalfToppings = toObservable([]);
ObservableList<String> wholeToppings = toObservable([]);
Pizza() {
firstHalfToppings.changes.listen((_)=> notifyChange(_));
secondHalfToppings.changes.listen((_)=> notifyChange(_));
wholeToppings.changes.listen((_)=> notifyChange(_));
}
}
Back in the MDV class, updatePizzaState needs only a new secondary method call, to the new _updateAttributes() method which simply assigns the three attributes::
// ...
updatePizzaState([_]) {
_updateText();
_updateGraphic();
_updateAttributes();
}
// ...
_updateAttributes() {
toppings = model.wholeToppings.join(',');
toppings1 = model.firstHalfToppings.join(',');
toppings2 = model.secondHalfToppings.join(',');
}
// ...And that does the trick nicely:
I am not sure that is the simplest solution possible, so I had hoped to drive some of this with tests. Unfortunately, testing turns out to be a little harder than expected. But that's a tale for tomorrow. For today, I am happy that updating attributes had no unexpected surprises.
Day #79
Dart code is still difficult to read for me: all those ([]) and (_) and (',') and ({})....! Somebody should write a Dart Cheat Sheet for those enigmatic notations. For example: ([]) = ( new List() ).
ReplyDelete