Reputation: 791
I am writing a polymer app. I extend a polymer element as follows:
@CustomTag("custom-element")
class CustomElement extends PolymerElement {
@published List<String> years;
CustomElement.created() : super.created();
}
the corresponding html:
<link rel="import" href="../../../../packages/polymer/polymer.html">
<polymer-element name="custom-element" attributes="years">
<template>
Years listed are
<template repeat="{{ year in years }}">
<p> {{ year }} </p>
</template>
</template>
<script type="application/dart" src="custom_element.dart"></script>
</polymer-element>
and in a dart script referenced in the entry html file, after I have fetched some data from server I dynamically create such elements:
initPolymer().run((){
querySelect("#custom-elements").children.add(
new Element.tag("custom-element")
..id = "my_custom_element"
);
});
Given code works fine if years
in CustomElement
is set to some value, now I want to set it in my main script. If the property years
was of type String
then I would simply altered the last piece to
initPolymer().run((){
querySelect("#custom-elements").children.add(
new Element.tag("custom-element")
..id = "my_custom_element"
..setAttribute("years", "2010")
);
});
But the problem is that I need to set a whole List
, not a single value. I can't figure out a way to do so. How would I go about this? Solutions and suggestions are very welcome.
EDIT: So my main script looks as follow
void main(){
// in reality this list is fetched from the server
List<String> customYears = ['2010', '2011'];
initPolymer().run((){
querySelect("#custom-elements").children.add(
new Element.tag("custom-element")
..id = "my_custom_element"
// HERE I would like to set a public field *years*
// of the CustomElement
// the following does not work
// 1.
// ..setAttribute('years', customYears)
// Exception: Uncaught Error: type 'List' is not a subtype of type 'String' of 'value'.
// 2.
// ..setAttribute('years', toObservale(customYears))
// Exception: Uncaught Error: type 'ObservableList' is not a subtype of type 'String' of 'value'.
// 3.
// ..years = customYears
// ..years = toObservable( custom Years )
// NoSuchMethodError: method not found: 'years='
);
});
}
So the question is, how do I assign a value to a non-string member field of an instance of CustomElement outside the class itself? A straightforward assignment inside the class causes no problems, but this isn't what I seek for. I hope I explained myself more clearly now.
Upvotes: 1
Views: 130
Reputation: 658205
Basically @Ozan answers your actual question but there is an additional issue.
The element is not yet fully initialized when the code assigns the value. This is the reason Dart fails and tells you that HtmlElement doesn't have a setter years. After adding Polymer.onReady.then()
Polymer is fully initialized and the assignment works.
Hint: If you cast the created element to its concrete type you don't get a warning in DartEditor.
import 'package:polymer/polymer.dart';
import 'dart:html';
// added import to be able to use the type
import 'custom_element.dart';
void main() {
// in reality this list is fetched from the server
List<String> customYears = ['2010', '2011'];
// Polymer => 0.16.0
initPolymer().then((zone) => zone.run(() {
Polymer.onReady.then((_) { // added - wait for onReady
querySelector("#custom-elements").children.add(
(new Element.tag('custom-element') as CustomElement)
..id = "my_custom_element"
..years = toObservable(customYears));
});
}));
}
it is more convenient to add a constructor to the custom element like
import 'package:polymer/polymer.dart';
import 'dart:html';
@CustomTag('custom-element')
class CustomElement extends PolymerElement {
factory CustomElement() {
final x = new Element.tag('custom-element');
return x;
}
CustomElement.created() : super.created();
@published List<String> years;
}
then you can create the element like
querySelector("#custom-elements").children.add(
new AppElement()
..id = "my_custom_element"
..years = toObservable(customYears));
see also
Upvotes: 2
Reputation: 4415
Try to simply assign the value to the field:
import 'package:observe/observe.dart';
initPolymer().run((){
querySelect("#custom-elements").children.add(
new Element.tag("custom-element")
..id = "my_custom_element"
..years = toObservable(["2010"])
);
});
Usually custom elements are used in a main polymer element and attributes like years are bound to its scope:
<link rel="import" href="../../../../packages/polymer/polymer.html">
<polymer-element name="main-element">
<template>
<custom-element years="{{years}}"></custom-element>
</template>
<script type="application/dart" src="main_element.dart"></script>
</polymer-element>
@CustomTag("main-element")
class MainElement extends PolymerElement {
@published List<String> years = toObservable(["2010"]);
MainElement.created() : super.created();
}
Upvotes: 1