Let's say I have a component:
#Component(selector: 'app-menu',
templateUrl: '.../menu.html',
cssUrl: const ['.../menu.css'],
publishAs: 'Menu')
class MenuComponent {
bool showOptions = true;
void toggleOptions() {
showOptions = !showOptions;
}
}
And a view for the component:
<div class="menu" ng-click="Menu.toggleOptions()">
<span icon="drawer"></span>
<ul ng-show="Menu.showOptions" class="options">
<!-- I want put content here -->
</ul>
</div>
Finally, the usage (theoretically):
<app-menu>
<menu-item>Remove</menu-item>
</app-menu>
After running the program I'd like to see <menu-item>Remove</menu-item> inside shadow root where I've put <!-- I want put content here -->. I've read that there were a <content /> component but it isn't working like that (nothing happened, I've seen only <output/> element). Also I've tried ng-transclude directive with no success.
Can someone help me and point the right way to do this?
Well,
After some tests and looking into Angular Dart tutorials I've found a solution.
My example above isn't actually accurate. I've used an <li> element instead of <menu-item>. Somehow, when I changed "li" to "span" it just started working. Perhaps DOM parser have rejected "li" element before it has been attached into correct structure inside shadow root tree. I don't really know.
However right after the change it started working.
Related
I am at: https://elements.polymer-project.org/elements/paper-dialog-behavior?active=Polymer.PaperDialogBehavior
and decided to create a dialog by doing something like:
<dom-module id="sample-dialog">
<template>
<paper-dialog-impl>
<h2>{{title}}</h2>
<div>
<content></content>
</div>
<div class="buttons">
<paper-button dialog-dismiss on-tap="cancel">Cancel</paper-button>
<paper-button dialog-confirm on-tap="submit">Accept</paper-button>
</div>
</paper-dialog-impl>
</template>
</dom-module>
it renders to the screen, but has no styles. I read: paper-dialog-shared-styles.html provide styles for a header, content area, and an action area for buttons but i don't know how to implement it. I was trying to use a link tag but that wasn't working. Specifically I tried inside the template: <link rel="import" href="polymer_elements/src/paper-dialog-behavior/paper-dialog-shared-styles.html" />
In my dart file, i imported these too, thinking it woudl be resolved.
import 'package:polymer_elements/paper_button.dart';
import 'package:polymer_elements/paper_dialog_behavior.dart';
Edit: Right now, I have the class Implementation extending Polymer Element, which makes sense. I just wasnt sure if it needed to extend something else as well.
Edit 2: Updated this to be a standard paper-dialog instead, except now it wont render the item at all, even after updating the import in the dart backend.
After updating it to a paper dialog, there is a property that needs to be applied to the paper-dialog for it to be visible or not. that is the opened attribute.
Adding that to the inner paper-dialog makes it visible.
So, therefore, passing it down to the paper dialog by way of an outer opened, will make it toggle open/closed.
//in the sample-dialog dart
#property bool opened = false;
in the markup:
<paper-dialog opened$="{{opened}}" ...>
then now i can say either:
<sample-dialog></sample-dialog>
<sample-dialog opened></sample-dialog>
I have this core-drawer-panel and want the #navicon to toggle the drawer. Like in the examples.
Using on-click in the HTML and the following code in the dart file, I get a NoSuchMethod Error on the panel
void toggleDrawer() {
querySelector('#drawerPanel')..togglePanel();
}
Now I read that on-click is somewhat deprecated and I'm totally confused.
What is the best practice way to query elements and catch events like this one? I saw this question as well, but it's still not working for me.
See Günters answer first. Other than that, I found out how to do it like the article on dartlang.org suggests.
HTML
<core-drawer-panel id="drawerPanel">
<core-header-panel drawer>
<core-toolbar id="navheader'">
<span>Menu</span>
</core-toolbar>
<core-menu>
<core-item label="One"></core-item>
<core-item label="Two"></core-item>
</core-menu>
</core-header-panel>
<core-header-panel main>
<core-toolbar id="mainheader">
<paper-icon-button id="navicon" icon="menu"></paper-icon-button>
<span flex>Title</span>
</core-toolbar>
<div class="content">
If drawer is hidden, press button to display drawer.
</div>
</core-header-panel>
</core-drawer-panel>
Dart File
void attached() {
super.attached();
shadowRoot.querySelector('#navicon').on['tap'].listen(
(event) => toggleDrawer()
);
}
void toggleDrawer() {
shadowRoot.querySelector('#drawerPanel')..togglePanel();
}
on-tap instead of on-click provides better support on mobile platforms. on-tap 'includes' on-click.
See also Touch & gestures and When to use on-click or on-tap w/ Polymer?
You probably need shadowRoot.querySelector(....
The method mentioned in this answer: https://stackoverflow.com/a/19818178/194642 does not seem to work anymore. How does one use web component's element in angular.dart component?
#Component(
selector: "custom-elem",
template: "<div id='container-elem'> <content></content></div>")
class CustomElem extends ShadowRootAware{
onShadowRoot(_) {
//do something
}
}
Now, I would expect the following html fragment:
<custom-elem>
<span>Sample content</span>
</custom-elem>
to result in following within #shadow-root:
<div id='container-elem'>
<content>
<span>Sample content</span>
</content>
</div>
I'm not sure if I understand your question or your expected result correctly but the <content> tag works the way that <span>Sample content</span> are children of <custom-elem> where <div id='container-elem'> is put in the Shadow DOM of <custom-elem> before the children and </div> in the Shadow DOM of <custom-elem> after the children but the <span> is in the light DOM like it would be when used like
<div>
<span>Sample content</span>
</div>
When you inspect the Shadow DOM of <custom-elem> there should just be the template part of your Angular component.
I'm wondering if it's possible to assign a class to the component element itself.
Let's say I have this component:
<html>
<body>
<element name="x-preview" constructor="PreviewComponent" extends="div" class="preview">
<template>
<div class="preview">
</div>
</template>
</element>
</body>
</html>
Now I would like to be able to remove the <div class="preview"> element inside, since I already have the wrapping x-preview div. Simply setting class="preview" on the <element> doesn't work.
Is it possible to do that?
You have two options that I am aware of:
1) Assign the class wherever you use it:
<div is="x-preview" class="preview"></div>
The problem with this method is that if you change the class name, you will have to change it anywhere the component is used.
2) Use the inserted lifecycle method to add the class to the root element:
void inserted() {
getShadowRoot('x-preview').attributes['class'] = 'preview';
}
inserted() will be called whenever the component is added to the DOM. getShadowRoot() will fetch the root element of the component and then set the class to 'preview'. The advantage of this method is you only change the class in one location.
I'm working on my first Dart app, having completed the Game of Darts tutorials. I am trying to create a semantically named top-menu element that will eventually display a list of navigation menu tabs at the top of my page. My Dart app is able to recognize my custom element and calls the associated constructor.
However, I am getting a null reference when trying to query for the UL element within my custom element. I need the UL reference in order to dynamically load my LI elements into the menu.
Question 1:
Should the element be visible in the DOM at the point where the constructor is running?
Question 2:
If it is not yet visible, is there a Dart event I can use to trigger loading of the LI elements after the custom element has been completely loaded into the DOM?
Thanks in advance! For reference, here is the source of my custom element:
topmenu-element.html
<!DOCTYPE html>
<html>
<body>
<element name="top-menu" constructor="TopMenu" extends="div">
<template>
<div>
Top Menu
<ul id="top-menu-list"></ul>
</div>
</template>
<script type="application/dart" src="topmenu-element.dart"></script>
</element>
</body>
</html>
topmenu-element.dart
import 'package:web_ui/web_ui.dart';
import 'dart:html';
class TopMenu extends WebComponent {
List menuItems = ['Session', 'Authentication Services', 'Vehicle Services', 'Subscriber Services', 'Data Services'];
void populateMenu() {
UListElement menuList = query('#top-menu-list');
LIElement newMenuItem = new LIElement();
newMenuItem.text = menuItems[0];
menuList.children.add(newMenuItem);
}
TopMenu() {
// populateMenu();
}
}
I can't speak specifically about the DOM visibility in a constructor with the query method as I'm truthfully not certain. However there are perhaps better methods which you can use, which are called at various stages in the elements lifecycle.
That said, can I ask why you need to use this particular method to add the children. It is probably much easier to do it with the template repeat like so:
<!DOCTYPE html>
<html>
<body>
<element name="top-menu" constructor="TopMenu" extends="div">
<template>
<div>
Top Menu
<ul id="top-menu-list">
<li template repeat="item in menuItems">{{item}}</li>
</ul>
</div>
</template>
<script type="application/dart" src="topmenu-element.dart"></script>
</element>
</body>
</html>
Then there's no need to put any of your menu display code in your constructor.