Reputation: 360
I am trying to create a custom 'radial-selector' element using Polymer in Dart.
My current goal is to make a 'children' field for the RadialSelector class that is observable, so that I can do a template loop through the children and filter through those that are only of a certain element type.
It is not clear how I can make the 'children' field observable without creating another variable that does not conflict with it in terms of namespace. For example, I could just create a "childs" field, make it observable, and then set it equal to this.children. But this seems awkward and boilerplate.
Is there a way for my RadialSelector class, which extends the PolymerElement class, to make its superclass 'children' field observable? Currently when I just write @observable children, Dart (understandably) thinks I'm just creating a new 'children' variable.
Thank you and let me know if there is something I could make clearer! :)
Here is the Dart Code:
import 'package:polymer/polymer.dart';
import 'dart:html';
@CustomTag('radial-selector')
class RadialSelector extends PolymerElement {
@published String img;
@observable children;
RadialSelector.created() : super.created() {
print("CONSTRUCTING RADIAL SELECTOR");
print(children);
}
filterByType(Type t, List<Element> elems) {
print("FILTER BY TYPE CALLED");
List<Element> newElems = new List<Element>();
for (var e in elems) {
if (e.runtimeType == t)
newElems.add(e);
}
return newElems;
}
}
Here is the corresponding html:
<link rel="import" href="packages/polymer_ui_elements/polymer_ui_icon_button/polymer_ui_icon_button.html">
<polymer-element name="radial-selector">
<template>
<style>
:host {
display: block;
margin: 100px
}
</style>
<script>console.log("HEY");</script>
<div id="stem">
<img src = "{{img}}" alt ="Radial stem"/>
<template repeat = "{{child in children | filterByType(ImageElement)}}">
<polymer-ui-icon-button src = {{child.src}}></polymer-ui-icon-button>
</template>
</div>
</template>
<script type="application/dart" src="radialselector.dart"></script>
</polymer-element>
Upvotes: 1
Views: 306
Reputation: 657666
There is no way you can do this for children
.
You could make an @observable getter/setter that redirects to the super class' children
@observable
NodeList get children => super.children;
set children(NodeList val) => super.children = val; // won't work
This has two flaws.
children
list is final
(haven't tried but I'm sure you can't assign a new list.@observable children
.children
by toObservable(children)
which is not possible because you can't replace the children
collection.What you can do is to use a MutationObserver
. see Angular Dart - execute a function right after ng-repeat has finished to get notified about child node changes.
You can add a new field
@observable List myChildren;
and use the mutation observer to update this field whenever the children change.
void mutationCallback(...) {
...
myChildren = children.toList();
}
This way each time your children change myChildren
get's an entire new list assigned and the view gets notified about this change due to the @observable
annotation.
You don't need to make the list observable because there are no single add/remove/replace operations to observe.
Upvotes: 1