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