There seems to be a good amount of confusion surrounding the new
@PublishedProperty
annotation in version 0.12 of Polymer.dart. Fair enough, I am always good for piling on more confusion. Consider my venerable
<x-pizza>
element. I might want to publish it with an attribute that specifies a specialty pizza name: <h1>Ye Olde Dart Pizza Shoppe</h1>
<x-pizza special_name="Plain"></x-pizza>
In older version of Polymer.dart, I would have supported this with a @published
annotation in the backing class like so:@CustomTag('x-pizza') class XPizza extends PolymerElement { // ... @published special_name; // ... }The new way of expressing this same intent is:
@CustomTag('x-pizza') class XPizza extends PolymerElement { // ... @published String get special_name => readValue(#special_name); set special_name(String newValue) => writeValue(#special_name, newValue); // ... }This is… pretty ugly. My understanding is that there are “timing” issues that necessitate writing it like that, but unless I experience said issues, I would likely continue using the old version.
Anyhow, I am trying to play with the
@PublishedProperty
annotation. At first, I try using this like the regular @published
annotation:@CustomTag('x-pizza') class XPizza extends PolymerElement { // ... @PublishedProperty String get special_name => readValue(#special_name); set special_name(String newValue) => writeValue(#special_name, newValue); // ... }But am greeted by a nasty error when trying to serve this element via
pub serve
:Build error: Transform ScriptCompactor on published_example|web/index.html threw error: The null object does not have a getter 'arguments'. NoSuchMethodError: method not found: 'arguments' Receiver: null Arguments: [] dart:core-patch/object_patch.dart 45 Object.noSuchMethod http://127.0.0.1:36253/packages/smoke/codegen/recorder.dart 268:44 _convertAnnotation dart:_internal/iterable.dart 393 MappedListIterable.elementAt dart:_internal/iterable.dart 214 ListIterable.toList ...The actual error goes on for a long time. It takes me a bit of time to realize that the
@PublishedProperty
annotation has a required argument, which looks like an optional named parameter::@CustomTag('x-pizza') class XPizza extends PolymerElement { // ... @PublishedProperty(reflect: true) String get special_name => readValue(#special_name); set special_name(String newValue) => writeValue(#special_name, newValue); // ... }Which re-publishes the attribute back to the element itself. To verify this, I add a conditional in the
updatePizza()
method to change the specialty name if the first half of the pizza has one topping and it is pepperoni:@CustomTag('x-pizza') class XPizza extends PolymerElement { // ... updatePizzaState([_]) { var first = $['firstHalfToppings'].model; if (first.length == 1 && first[0] == 'pepperoni') { special_name = 'First Half Pepperoni'; } // ... } }Sure enough, if I add pepperoni to the first half, the attribute changes back in the DOM from “Plain”:
To the new “First Half Pepperoni” special name:
If I switch back to the
@published
annotation, then even though special_name
is still being updated, the published attribute no longer reflects the change. The value of the special_name
attribute in the DOM always remains “Plain.”Interestingly,
@PublishedProperty(reflect: false)
seems to behave the same as @published
. I am unsure if there is a difference or if reflect: false
is only meant as a similar looking alternative when some attributes require reflect: true
. The documentation mentions something about serializing, but initial attempts at converting to something that might be serialized (like a List) do not seem to work.I am not thrilled with the new annotation—especially the verbosity of the setter and getter. Still, the functionality is nice. I wonder if this might make it easier to synchronize changes between Polymer.dart and Angular.dart. Something to investigate another day.
Day #142
No comments:
Post a Comment