Only one reference to <content></content> in polymer element? - dart-polymer

The boildown of the construct, is like this. Having a polymer element:
<dom-module id="demo-element">
<template>
<span><content></content></span>
<span><content></content></span>
</template>
</dom-module>
This only gives one occurrence of content. e.g.
<demo-element>Hello</demo-element> only gives "Hello" and not "HelloHello". Using a property with binding, gives the expected. Seems like some small detail missing, anyone who have been in similar parts?
Environment:
Dart version 1.14.0
WebStorm 11.0.3
From pubspec.yaml:
environment:
sdk: '>=1.9.0 <2.0.0'
dependencies:
polymer: ^1.0.0-rc.15
web_components: ^0.12.0
polymer_elements: 1.0.0-rc.8
browser: ^0.10.0
reflectable: ^0.5.0
polymer_interop: ^1.0.0-rc.5

That's by design. <content> doesn't produce elements, it just projects them.
More than one <content> without a selector doesn't do anything. The first one "grabs" all children and projects them where it is placed.
You can have more than one <content> tag but then they should have different selectors like
<header-elem>
<content select=".header"></content>
</header-elem>
<drawer-elem>
<content select=".drawer"></content>
</drawer-elem>
<body-elem>
<content></content>
</body-elem>
used like
<my-component>
<div>body</div>
<div class"header">header</div>
<div class"drawer">header</div>
</my-component>
then the first <div> is projected to the last <content> element because it doesn't match any specific selector, the other divs are projected to the <content> tags with the matching selectors.

Related

Dart Polymer 1 - How to detect changes to <content> nested components

Given custom component A:
<dom-module id="my-a-component">
<template>
<content id="nestednodes"></content>
</template>
</dom-module>
Then:
<my-a-component>
<my-b-component label='{{blabel}}'></my-b-component>
</my-a-component>
How can I get updated inside "my-a-component" when any children under "#nestednodes" is updated? or, when a new component gets added to the <content>?
I've been toying with MutationObserver but can't seem to see any updates to those nodes. Any guidance is highly appreciated.

Referencing in style.css to sdk definition e.g. color.dart

Having a polymer project using the material color definitions in import 'package:polymer_elements/color.dart'; The references to css styling e.g. var(--paper-green-300); works ok, when they are placed in the <style></style> section for the element, but when I move this to the style.css, they aren't found. I have tried with different combinations of include in index.html and index.dart. E.g. in index.html at <head> section <link rel="import" href="packages/polymer_elements/color.html"> but doesn't seems to do the trick. Anyone who have experience with similar issues?
Of course not a high prio project killer, simple to use the hard coded values or leave the definitions in the <style> section for every element. But this way things will be more tidy.
Environment
Dart version 1.14.0
WebStorm 11.0.3
From pubspec.yaml:
environment:
sdk: '>=1.9.0 <2.0.0'
dependencies:
polymer: ^1.0.0-rc.15
web_components: ^0.12.0
polymer_elements: 1.0.0-rc.8
browser: ^0.10.0
reflectable: ^0.5.0
polymer_interop: ^1.0.0-rc.5
CSS variables in Polymer only work in <style is="custom-style"> and therefore not in .css files.
is="custom-style" is implicit for style tags within Polymer elements and can and should be omitted.

Dart data binding from a parent custom element to attributes of a child custom element

Here is a problem that cropped up today when I updated to the latest Dart libs.
The child custom element is a combo box. The parent custom element fills it with a varying list of strings.
// child HTML
<polymer-element name="bx-icombo" attributes="aLabel aList aSelected">
<template>
<div class='outr' flex layout horizontal center>
<label for='inp' flex end-justified>{{aLabel}}</label>
<!-- wait until the data is available -->
<template if='{{aList}}'>
<paper-dropdown-menu id='inp' label='aLabel' valign='top' flex start-justified >
<paper-dropdown class="dropdown">
<core-menu id='m' class="menu" selected="{{aSelected}}">
<template repeat='{{aList}}'>
<paper-item name='{{}}'>{{}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
</template>
</div>
</template>
<script type='application/dart' src='bx_icombo.dart'></script>
</polymer-element>
//---------------------------------------------------------------
// child Dart
#CustomTag('bx-icombo')
class BxICombo extends PolymerElement {
#PublishedProperty(reflect: true) String aLabel;
#PublishedProperty(reflect: true) List<String> aList;
#PublishedProperty(reflect: true) String aSelected;
BxICombo.created() : super.created();
}
//---------------------------------------------------------------
// Parent HTML
<polymer-element name="tst-sigs">
<template>
<paper-dialog backdrop heading='Sigs' closeSelector=''>
<bx-icombo aLabel='{{selectAsignal}}'
aList='{{sigsList}}'
aSelected='{{sigsSel}}'>
</bx-icombo>
</paper-dialog>
</template>
<script type='application/dart' src='tst_sigs.dart'></script>
</polymer-element>
//---------------------------------------------------------------
// Parent Dart
#CustomTag('tst-sigs')
class TstSigs extends PolymerElement {
#observable List<String> sigsList = ['alpha', 'beta', 'gamma'];
#observable String sigsSel;
#observable String selectAsignal = 'Select a Signal';
TstSigs.created() : super.created();
}
//---------------------------------------------------------------
Dartium reports:
Attributes on bx-icombo were data bound prior to Polymer upgrading the element. This may result in incorrect binding types. (:1)
So what has to be changed? #PublishedProperty or #observable or #published or .... I admit to finding the maze of #... annotations deeply unclear.
The versions are:
Dart: 1.9.3 (STABLE)
Dartium: 39.0.2171.99
and packages:
analyzer 0.24.6 (0.25.0+1 available)
args 0.12.2+6 (0.13.0 available)
barback 0.15.2+4
browser 0.10.0+2
cli_util 0.0.1+1
code_transformers 0.2.8
collection 1.1.0
core_elements 0.7.1+2
csslib 0.12.0
dart_style 0.1.8
glob 1.0.4
html 0.12.1+1
ini 1.1.0
initialize 0.6.0+4
intl 0.12.2
js 0.3.0
logging 0.9.3 (0.10.0 available)
markdown 0.7.1+2
matcher 0.11.4+4 (0.12.0-alpha.0 available)
observe 0.13.0+2
paper_elements 0.7.1
path 1.3.5
petitparser 1.3.7
polymer 0.16.1+4
polymer_expressions 0.13.1
polymer_interop 0.1.0+2
pool 1.0.1
quiver 0.21.3
smoke 0.3.2
source_maps 0.10.0+2
source_span 1.1.2
stack_trace 1.3.1
string_scanner 0.1.3+1
template_binding 0.14.0+2
utf 0.9.0+2
watcher 0.9.5
web_components 0.11.2
when 0.2.0
which 0.1.3
yaml 2.1.2
Initially a problem with code-transformers forced code_transformers < 0.2.5 and that limited polymer to 0.16.0. It looks as if the code transformer thing has been resolved so I have removed the version constraint and polymer updated to 0.16.1. The problem remains.
The main function is
import 'package:polymer/polymer.dart';
import 'lib/bxglobs/bxGlobs.dart' as G;
void realMain() {
// empty for this test
}
void main() {
G.initGlobals();
initPolymer().then((zone) => zone.run(() {
Polymer.onReady.then((_) => realMain());
}));
}
and pubspec.yaml:
name: bxPoly
description: BX GUI
dependencies:
core_elements: any
ini: any
intl: any
js: any
markdown: any
paper_elements: any
polymer: any
code_transformers: any
transformers:
- polymer:
entry_points:
- web/test.html
This error almost always occurs because of elements getting registered in the wrong order. Specifically, a parent element being registered before a child element.
This is hard to diagnose without full access to the code, but following these two rules should ensure its not an issue:
Put each polymer-element in its own html file, and each class in its own dart library (using parts especially causes issues).
Make sure your elements import all of their dependencies.
edit
<template if='{{aList != null}}'>
<paper-dropdown-menu id='inp' label='aLabel' valign='top' flex start-justified >
<paper-dropdown class="dropdown">
<core-menu id='m' class="menu" selected="{{aSelected}}">
<template repeat='{{a in aList}}'>
<paper-item name='{{a}}'>{{a}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
original
If you bind from the shadow DOM of an element to its class #observable is enough.
If you want to bind to attributes from outside of an element use #published.
If you want to use the value of a bound attribute for example in CSS selectors use #PublishedAttribute(reflect: true). reflect means the properties value is reflected to the DOM, otherwise it's only available for Polymer and Dart code.
I haven't seen this error message before. Maybe there is a problem with Polymer initialization. Do you have a custom main? Can you add it to your question?
class MyA extends PolymerElement {
#observable
aobservable = 'obs';
#published
apublished = 'pub';
#PublishedAttribute(reflect: true)
areflected = 'ref';
}
<polymer-element name="my-a">
<template>
<!-- doesn't work
<my-b bobservable="{{aobservable}}"></my-b> -->
<my-b bpublished="{{aobservable}}"></my-b>
<my-b breflected="{{aobservable}}"></my-b>
<!-- you can bind properties of MyA here no matter if
they are observable/published/reflected
(even when they have no annotation but they will not
be updated when the value changes)
You can bind only to published (reflected or not)
attributes of MyB
-->
</template>
</polymer-element>
class MyB extends PolymerElement {
#observable
bobservable = 'obs';
#published
bpublished = 'pub';
#PublishedAttribute(reflect: true)
breflected = 'rep';
}
<polymer-element name="my-b">
<template>
</template>
</polymer-element>
<head>
<style>
// you can only address reflected attributes here
my-a[areflected="ref"] {
backgroundColor: red;
}
</style>
</head>
<body>
<my-a></my-a>
</body>
This seems to be the solution. Based on debugging rather than knowledge, so beware..
Say your component foo.dart and foo.html refers to another component bar.dart and bar.html. For instance, the reference might be:
barEl el = document.querySelector('bar');
Obviously you import bar.dart at the top of foo.dart. You get the error described unless you also
<link rel="import" href="bar.html">
at the top of foo.html. Even though bar.html is not conventionally referenced in foo.html.

Polymer elements not working after pub build - Did I forget something?

so my Polymer.Dart project is running fine in Chromium (running on Dart code) but when I pub upgrade and pub build the sampler-scaffold keeps working but paper-button, paper-dialog, paper-progress... elements are just not showing up!
My HTML file looks like this
<link href='http://fonts.googleapis.com/css?family=Droid+Serif|Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link rel="import" href="packages/paper_elements/paper_button.html">
<link rel="import" href="packages/paper_elements/paper_dialog_transition.html">
<link rel="import" href="packages/paper_elements/paper_dialog.html">
<link rel="stylesheet" href="css/reset.css"> <!-- CSS reset -->
<link rel="stylesheet" href="css/style.css"> <!-- Resource style -->
...
<paper-button id="infoUPC" class="cd-read-more" raised>Read more</paper-button>
...
<script src="education.dart" type="application/dart"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="js/main.js"></script> <!-- Resource jQuery -->
<script src="js/modernizr.js"></script> <!-- Modernizr -->
education.dart
import 'package:polymer/polymer.dart';
import 'dart:html';
import 'package:paper_elements/paper_dialog.dart';
main() {
initPolymer().run(() {
Polymer.onReady.then((_) {
querySelector('#infoFHV').onClick.listen(
(_) => toggleDialog('fhv'));
querySelector('#infoUPC').onClick.listen(
(_) => toggleDialog('upc'));
querySelector('#infoTU').onClick.listen(
(_) => toggleDialog('tu'));
});
});
}
toggleDialog(language) =>
(querySelector('paper-dialog[edu=$language]') as PaperDialog)
.toggle();
pubspec.yaml
name: polydart_resume
version: 0.0.1
author: Shady
description: Test app
dependencies:
core_elements: '>=0.3.2 <0.5.0'
custom_element_apigen: ">= 0.1.1 <0.2.0"
polymer: ">=0.14.0 <0.16.0"
web_components: ">=0.9.0 <0.10.0"
paper_elements: ">=0.5.0 <0.6.0"
transformers:
- polymer:
entry_points:
- web/index.html
pub build does not give me any warnings or errors on these files, but I'm surely missing something right?
You have two entry pages index.html and languages.html. Only languages.html calls your custom main() but only index.html is in your pubspec.yaml transformer configuration.
index.html will invoke the default main() method provided by Polymer but not your custom main() because of this script tag
<script type="application/dart">export 'package:polymer/init.dart';</script>
languages.html has the correct script tag
<script type="application/dart" src="languages.dart"></script>
but this doesn't work as expected because languages.html is not listed in your Polymer transformer entry_points configuration
transformers:
- polymer:
entry_points:
# - web/index.html
- web/languages.html
From the comments:
Q: Do you load languages.html from a link in drawer.html (<core-item label="Languages" url="chapters/languages.html"></core-item>)? – Günter Zöchbauer 25 mins ago
A: Yessir thats exactly what I'm doing.
This isn't how one usually develops applications in Dart. You can, but Dart is for SPA (http://en.wikipedia.org/wiki/Single-page_application).
If you load another page from a Dart application this is like launching an entirly different application. Each page (app) loaded this way needs all parts of a Polymer application to work.
Usually in Dart you have only one entry page (entry_point) and when you want to change what is shown to the user (a new view) you replace the content in the current page instead of loading another one (this is for example where Polymer elements are handy for, you just remove one element (view) and add another one).
Dart also has a rather large boilerplate code size which has to be loaded each time you load another page which is rather inefficient.
Because my problem was not really code related but more fundamental, I found a sample project on www.polymer-project.org where one can see a recommended routing method. I find the introduction docs on polymer don't cover this topic good enough...

Polymer Elements in Dart Packages

I have a dart package that contains three extensions of polymer element: tp-element-a, tp-element-b and tp-element-c. For each of these elements there is a html-file containing the markup of the element and a dart file for the code. The tp-element-c contains references to the tp-element-a and tp-element-b.
The package structure looks like this:
testpolymer
pubspec.yaml
- packages
- asset
tp-element-a.html
tp-element-b.html
tp-element-c.html
- lib
testpolymer.dart
tp-element-a.dart
tp-element-b.dart
tp-element-c.dart
- web
index.html
The definitiopn of the polymer elements are very simple:
tp-element-a.html
<polymer-element name="tp-element-a">
<template>
<h1>Hello Element A</h1>
</template>
<script type="application/dart" src="../lib/tp-element-a.dart"></script>
</polymer-element>
tp-element-a.dart
part of testpolymer;
#CustomTag("tp-element-a")
class TpElementA extends PolymerElement {
TpElementA.created() : super.created() {}
}
I skip the definitions of tp-element-b and tp-element-c. They are similar. With the only difference that tp-element-c uses the tp-element-a and tp-element-b within its template markup.
The file testpolymer.dart contains the definition of the library testpolymer:
library testpolymer;
import "package:polymer/polymer.dart";
part "tp-element-a.dart";
part "tp-element-b.dart";
part "tp-element-c.dart";
In the yaml file I decalre the dependency to the polymer package and add the polymer transformer:
name: testpolymer
description: A pub package
dependencies:
polymer: any
transformers:
- polymer:
entry_points: web/index.html
Last not least the index.html just contains the link to the tp-element-c.html and uses this element:
<html>
<head>
<link rel="import" href="../asset/tp-element-c.html">
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
</head>
<body>
<div id="sample_container_id">
<tp-element-c></tp-element-c>
</div>
</body>
</html>
So far so good. But when I run a pub build I get errors, that are probably all caused by organizing the dart files in a library:
packages/testpolymer/tp-element-a.dart:1:1:
Directive not allowed here.
part of testpolymer;
packages/testpolymer/tp-element-a.dart:4:26:
A class can't extend a malformed type.
Try correcting the malformed type annotation or removing the 'extends' clause.
class TpElementA extends PolymerElement {
packages/testpolymer/tp-element-a.dart:3:2:
Cannot resolve 'CustomTag'.
#CustomTag("tp-element-a")
So how is it possible to include the code for polymer elements in libraries?
If I don't organize the polymer code as a library, I get another error in tp-element-c.dart, which imports (if no library is used) the tp-element-a.dart and the tp-element-b.dart directly:
The imported libraries 'tp-element-a.dart' and 'tp-element-b.dart' should not have the same name ''
How can I resolve this puzzle?
You get the last error message, if you don't have in each dart file unique library uniquename; definitions. In your case names could be: tp-element-a, tp-element-b etc.

Resources