I'm trying to build a component that can switch other components in and out, almost like pages, but with no change in URL.
I have a polymer element that contains a content div:
<link rel="import" href="../../packages/polymer/polymer.html">
<link rel="import" href="../../packages/paper_elements/paper_input.html">
<link rel="import" href="../../packages/paper_elements/paper_input.html">
<link rel="import" href="../../packages/paper_elements/paper_tabs.html">
<link rel="import" href="../../packages/paper_elements/paper_dialog.html">
<link rel="import" href="../../packages/paper_elements/paper_icon_button.html">
<link rel="import" href="../../packages/core_elements/core_toolbar.html">
<link rel="import" href="../../packages/core_elements/core_scaffold.html">
<link rel="import" href="../../packages/core_elements/core_header_panel.html">
<link rel="import" href="../../packages/core_elements/core_menu.html">
<link rel="import" href="../../packages/core_elements/core_item.html">
<link rel="import" href="../../packages/paper_elements/paper_input.html">
<link rel="import" href="../../packages/paper_elements/paper_button.html">
<polymer-element name="navigation-toolbar" class="dark-primary-color">
<template>
<style type="text/css">
:host {
display: block;
}
</style>
<core-scaffold>
<core-header-panel id="menu-panel" navigation flex>
<core-toolbar id="navheader">
<span>Menu</span>
</core-toolbar>
<core-menu>
<core-item label="A" on-click="{{aClicked}}"></core-item>
<core-item label="B" on-click="{{bClicked}}"></core-item>
<core-item label="C" on-click="{{cClicked}}"></core-item>
</core-menu>
</core-header-panel>
<span tool>{{title}}</span>
<paper-tabs class="main-menu bottom fit" selected="0">
<paper-tab on-click="{{aClicked}}">A</paper-tab>
<paper-tab on-click="{{bClicked}}">B</paper-tab>
<paper-tab on-click="{{cClicked}}">C</paper-tab>
</paper-tabs>
<div class="content" forceNarrow>
<p>Lorem ipsum ...</p>
</div>
</core-scaffold>
</template>
<script type="application/dart" src="navigation-toolbar.dart"></script>
</polymer-element>
I have an eventbus that fires events and receives events, it is used all over the application to allow me to decouple components.
part of util;
class EB {
static EventBus _eventBus = new EventBus();
static fire(event){
_eventBus.fire(event);
}
static Stream on([Type eventType]) {
return _eventBus.on(eventType);
}
}
PageEvent which is being used to fire / listen for page events is just a PODO:
part of event;
class PageEvent {
String page;
String title;
PolymerElement element;
PageEvent.create(String page, String title, PolymerElement element){
this.page = page;
this.title = title;
this.element = element;
}
}
Inside the event library the relevant imports is being done for PageEvent:
library event;
import 'package:polymer/polymer.dart';
part 'login-event.dart';
part 'logout-event.dart';
part 'page-event.dart';
...
This event bus is then used in my core-scaffold component:
import 'package:polymer/polymer.dart';
import 'util/util.dart';
import 'event/event.dart';
import 'page/page.dart';
import 'dart:html';
@CustomTag('navigation-toolbar')
class NavigationToolbar extends PolymerElement {
@observable String page = "home";
@observable String title = "Home";
NavigationToolbar.created() : super.created() {
EB.on(PageEvent).listen((PageEvent e) {
this.page = e.page;
this.title = e.title;
setPage(e.element);
});
An event is fired upon clicking on one of the paper-tabs:
// part of navigation-toolbar
aClicked(event, detail, target) {
EB.fire(new PageEvent.create("a", "A", new APage()));
}
setPage is where the final magic is supposed to happen, but is not, both div and e is being printed out which tells me it is getting to the method and both e and div are not null:
// part of navigation-toolbar
setPage(PolymerElement e) {
DivElement div = shadowRoot.querySelector("core-scaffold").querySelector(".content");
Node node = div.lastChild;
while (node != null) {
node.remove();
node = div.lastChild;
}
print(div);
print(e);
div.children.add(e);
}
Printing out div, I can see the word div in the console which means it's not null, printing out e, I can see a-page, b-page, c-page, etc, that's not null either.
The code to clear the div works, it removes all content. The part that doesn't work is the div.children.add(e);
APage looks like this:
<link rel="import" href="../../../packages/polymer/polymer.html">
<polymer-element name="home-page" class="dark-primary-color">
<template>
<div>
A Page
</div>
</template>
<script type="application/dart" src="a-page.dart"></script>
</polymer-element>
and a-page.dart:
part of page;
@CustomTag('a-page')
class APage extends PolymerElement {
APage.created() : super.created();
factory APage() => new Element.tag('a-page');
}
Adding an import for a-page.html in navigation-toolbar.html
<link rel="import" href="page/a-page.html">
Gives me the following exception:
'package:falm/page/a-page.dart': error: line 1 pos 6: url expected
part of page;
^: package:falm/page/a-page.dart
div.children.add(e);
doesn't work, what am I missing here?
After messing around a bit, I found a way that works - it seems polymer elements doesn't play nice when included in a library.
This was what a-page.dart looked like:
part of page;
@CustomTag('a-page')
class APage extends PolymerElement {
APage.created() : super.created();
factory APage() => new Element.tag('a-page');
}
and the page.dart library:
library page;
import 'package:polymer/polymer.dart';
import 'dart:html';
part 'a-page.dart';
part 'b-page.dart';
part 'c-page.dart';
After removing the page library and putting all the dependencies straight inside a-page.dart:
import 'package:polymer/polymer.dart';
import 'dart:html';
@CustomTag('a-page')
class APage extends PolymerElement {
APage.created() : super.created();
factory APage() => new Element.tag('a-page');
}
inside my navigation-toolbar.dart, instead of importing page/page.dart, I need to import each page individually:
import 'page/a-page.dart';
import 'page/b-page.dart';
import 'page/c-page.dart';
...
setPage(PolymerElement e) {
DivElement div = shadowRoot.querySelector("core-scaffold .content")
..children.clear()
..append(e);
}
and on navigation-toolbar.html, I need to import each html component as well for it to work:
<link rel="import" href="page/a-page.html">
<link rel="import" href="page/b-page.html">
<link rel="import" href="page/c-page.html">
Is it even possible to include polymer elements in a library?