Reputation: 1377
I'm building up a set of polymer components, starting with simpler more generic components (e.g. a simple wrapper around a canvas) to higher level components (e.g. something that uses the simple canvas wrapper for a specific type of drawing).
Once I get to around 3 deep I can't figure out how to populate the polymer element attributes of the simpler components. The main catch for me is that often the attributes of children are derived from attributes of the higher level components.
e.g starting with a simple low level component which just has a single attribute 'message'
<!DOCTYPE html>
<polymer-element name="foo-view" >
<template>
<p>
message: '{{message}}'
</p>
</template>
<script type="application/dart" src="foo.dart"></script>
</polymer-element>
library foo;
import 'package:polymer/polymer.dart';
@CustomTag('foo-view')
class FooViewElement extends PolymerElement {
@published String message;
FooViewElement.created() : super.created();
}
Then a higher level component that uses foo and derives foo's message attribute based on its own attribute 'bar'
<!DOCTYPE html>
<link rel="import" href="foo.html">
<polymer-element name="bar-view" >
<template>
<foo-view message="{{message}}" ></foo-view>
</template>
<script type="application/dart" src="bar.dart">
</script>
</polymer-element>
library bar;
import 'package:polymer/polymer.dart';
@CustomTag('bar-view')
class BarViewElement extends PolymerElement with ChangeNotifier {
String _bar;
@published String get bar {
return _bar;
}
@published void set bar(String b) {
_bar = b;
if (b != null) {
// derive the message property here
message = "this is what I expect to end up in foo.message";
}
}
@observable String message = "initial message";
BarViewElement.created() : super.created();
}
So my expectation (intention) is that when the bar attribute is set it calculates what message should be and sets that property. That in turn I expect would propagate into foo's message attribute and the value displayed should be 'this is what I expect to end up in foo.message'.
Obviously this is a silly example because I'm not really deriving the message field, but in my real world use case I am constructing and object at this point based on the one passed into the higher level component.
To test it I create an example component
<!DOCTYPE html>
<link rel="import" href="packages/polymerIssue1/bar.html">
<polymer-element name="example-ui" >
<template>
<bar-view bar="{{bar}}"></bar-view>
</template>
<script src="example_ui.dart" type="application/dart"></script>
</polymer-element>
library ui;
import 'package:polymer/polymer.dart';
@CustomTag('example-ui')
class ExampleUi extends PolymerElement {
// Note in my real world example this constructs a complex object
@observable String bar = 'this is the value of bar';
ExampleUi.created() : super.created();
}
And then a test page
<!DOCTYPE html>
<html>
<head>
<link rel="import" href="example_ui.html">
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<div>
<h3>example-ui</h3>
<example-ui></example-ui>
</div>
</body>
</html>
It displays message: 'initial message'
rather than message: 'this is what I expect to end up in foo.message'
I'm not sure if I've got it wrong; or there is a bug in polymer; or I am going about it completely wrong.
Upvotes: 1
Views: 180
Reputation: 658077
You mix encapsulation and inheritance.
When you extend the elements class you also have to set the extends
attribute in the HTML markup (bar.html
).
But in this case you don't embed you base element (foo-view
).
see extend_custom_element from Polymer examples
The last time I worked with extending custom elements it worked better when I declared the @published
attributes also in HTML <polymer-element name="foo-view" attributes="message">
(this shouldn't have been necessary, so this may be fixed in the meantime)
If you extend a Polymer element you should add a <shadow></shadow>
tag to the derived element. This is the place where the elements form the base element are inserted.
I suggest you try this and if you still don't get it working, update the question so that it shows how far you got and we/I take a look again.
Upvotes: 1