Using Polymers own behaviors in Polymer 2.x - polymer

I am experimenting with Polymer 2.x and what I don't understand is how to use Polymers own behaviors in Polymer 2.x, iron-resizable-behavior as an example.
The Polymer 2.0 upgrade guide tells us that for our own components we should work with class expression mixins. That's fine but what about Polymers own behaviors? Are they in the progress of being rewritten as mixins or will they remain unchanged? There is a Polymer.mixinBehaviors method that seems to allow me to use Polymer 1.x mixins. Is this the final solution or is this an intermediate step?
To phrase it another way: are the Polymer behaviors considered Polymer 2.x although we are told to use mixins for our own components?
Sources:
https://www.polymer-project.org/2.0/docs/upgrade#upgrading-to-class-based-elements
Applying Behaviors with JS Mixins in Polymer 2

class MyElement extends Polymer.mixinBehaviors([Polymer.IronFormElementBehavior], Polymer.Element) { ... }

I think Polymer has an API for that. I think it is dedupingMixin.
Below is an example how to create a mixin for your own behavior and how to use it in your element class.
var MyBehaviorMixin = Polymer.dedupingMixin(function(superClass){
return class MyBehavior extends superClass {
constructor() {
super();
}
methodInBehavior() {
return "this method is defined in Behavior";
}
}
}
class MyElement extends MyBehaviorMixin(Polymer.Element){
constructor(){
super();
console.log(this.methodInBehavior());
}
}

So I found a way how to use the iron-resizable-behavior in Polymer2
Instead of using the Mixin I am making use of the syntax of codeMonkey and extended his answer to show how to use it
As far as I know, this solution is a hybrid for Polymer 1 & 2
class customElement extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element) {
static get is() { return 'custom-element'; }
ready() {
super.ready();
this.addEventListener('iron-resize', () => { this.onWidthChange() });
}
onWidthChange() {
var w = this.offsetWidth;
if (w > 0)
console.log("Width of page is now ", w);
}
}

Related

is there a state management solution for lit-element?

If there is a list which should be rendered from an array, and the array will be passed from the grand-grand-grand-grand-grand-parent custom element. That will be super annoying.
Is there a global state management solution for lit-element, just like redux?
Yes, check out LitState (npm package name lit-element-state).
I created this specially for LitElement. It has the same mindset: simple, small and powerful.
Because it is created specially for LitElement, it integrates very well and therefore the usage is very simple. You make a state object like this:
import { LitState, stateVar } from 'lit-element-state';
class MyState extends LitState {
#stateVar() myCounter = 0;
}
export const myState = new MyState();
Usage without #decorators, look here.
Then you can use the state in your components like this:
import { LitElement, html } from 'lit-element';
import { observeState } from 'lit-element-state';
import { myState } from './my-state.js';
class MyComponent extends observeState(LitElement) {
render() {
return html`
<h1>Counter: ${myState.counter}</h1>
<button #click=${() => myState.counter++}></button>
`;
}
}
When you add the observeState() mixin to your component, the component will automatically re-render when any stateVar they use changes. You can do this with any amount of component and states and it will all automatically stay synchronized thanks to the observeState() mixin.
LitElement is a library and you can use any library for state management that you want. Just subscribe to the store in the constructor or connectedCallback (unsubscribe in disconnectedCallback) and change the components' properties when the store notifies you of a change.
Here you have some PWA helpers that works with litElement and you have one for Redux.
https://github.com/Polymer/pwa-helpers#connect-mixinjs
I am late in the game, but this can be quite usefull:
https://www.npmjs.com/package/#lit-app/state
#lit-app/state is a global state management, integrating with lit web-components.
Why a new state-management tool ?
There are plenty options available for state management, so why yet another one?
Some existing options are too heavy. In my opinion, managing state should be lean and simple. Redux, for instance falls into this category.
Some solutions designed for lit (for instance lit-state) do not support Typescript and do not take advantage of lit#2 Reactive Controlers, very well suited for hooking external features into templating lifecyce.
Some elegant ideas were worth pursuing (for instance this tweet, or this post.
How to use it?
import { State, StateController, property } from "#lit-app/state";
import { LitElement } from "lit";
// declare some state
class MyState extends State {
#property({value: 'Bob'}) name
}
const myState = new MyState()
// declare a component
class StateEl extends LitElement {
// StateController is a Reactive Controller binding myState with the element
state = new StateController(this, myState)
override render() {
return html`
<div>This will be updated when the state changes: ${myState.name}</div>
`;
}
}
// changing the state will reflect in the template
myState.name = 'Alice'
I'd look into MobX which is an extremely popular framework independent state management library
"MobX is unopinionated and allows you to manage your application state outside of any UI framework. This makes your code decoupled, portable, and above all, easily testable." - (Github)

Polymer: How to use imported function in computed binding

I'd like to use a shared function for computed bindings in different custom elements. Is this possible?
No matter how I import the shared function, I get console errors:
method `formatAmount` not defined
The computed binding is something like:
<span>[[formatAmount(amount)]]</span>
I've tried using a tag above the element. I've tried inside the element. And I've tried in index.html.
Do all computed binding methods need to be defined in the custom element and can't be shared? Do I have to use a mixin?
UPDATE: I've created an ugly work around where I define a private method on my custom element that calls the shared method. Then the private method is used in the computed binding. This is ugly because of the extra boilerplate.
...
<script src="format-amount.js"></script>
<dom-module id="my-foo">
<template>
...[[_formatAmount(amount)]]...
</template>
<script>
class MyFoo extends Polymer.Element {
...
_formatAmount(amount) {
return formatAmount(amount); // Defined in format-amount.js.
}
}
</script>
</dom-module>
This is similar question to what I have asked few months ago.
You can use mixin. A mixin is simply a function that takes a class and returns a subclass. If you want to learn more click here.
For your problem define mixin in separate html file say - my-mixin.html:
const MyMixin = (superClass) => class extends superClass {
constructor() {
super();
}
formatAmount(amount) {
//function contents
}
}
And then in your element import and add mixin:
<link rel="import" href="my-mixin.html">
class MyFoo extends MyMixin(Polymer.Element)
Then you can simply call the function from your element:
<template>
...[[formatAmount(amount)]]...
</template>
To access the function in script use super.formatAmount(amount).

Arrow functions within classes are not supported in chrome but work fine through babel, why?

The correct syntax for writing arrow functions within a class should be
greet = () => {console.log('greet')}
While this compiles fine in Babel (using es2015 default) the chrome devtools throws an error.
This confuses me, as according to http://caniuse.com/#feat=arrow-functions they are completely supported in Chrome.
Is this a non-standard syntax? If so, why is it supported in Babel. If not, where can I see the support status
You seem to be talking about the class fields proposal:
Field declarations
With the ESnext field declarations proposal, the above example can be written as
class Counter extends HTMLElement {
x = 0;
clicked() {
this.x++;
window.requestAnimationFrame(this.render.bind(this));
}
constructor() {
super();
this.onclick = this.clicked.bind(this);
}
connectedCallback() { this.render(); }
render() {
this.textContent = this.x.toString();
}
}
window.customElements.define('num-counter', Counter);
In the above example, you can see a field declared with the syntax x = 0. You can also declare a field without an initializer as x. By declaring fields up-front, class definitions become more self-documenting; instances go through fewer state transitions, as declared fields are always present.
It's a stage 3 proposal and has nothing to do with arrow functions. Any value can be assigned to a field, including arrow functions.
While this compiles fine in Babel (using es2015 default)
I'm sure other plugins are configured. Since this is a proposal and not part of ES2016, only enabling the ES2015 preset won't transform this syntax.

Flex custom toggleswitch not working in actionscript

I have a custom Flex Toggleswitch component that changes the text values of the switch.
package skins
{
import spark.skins.mobile.ToggleSwitchSkin;
public class MyToggleSwitchSkin extends ToggleSwitchSkin
{
public function MyToggleSwitchSkin()
{
super();
selectedLabel="Serviceable";
unselectedLabel="Fault";
}
}
}
If I add the control using the MXML tag, it works fine. However, when I add the component using action script, it does not.
import skins.MyToggleSwitchSkin;
public function addToggle():void {
var myCustomToggle:MyToggleSwitchSkin = new MyToggleSwitchSkin();
hgroup.addElement(myCustomToggle);
}
The control dsiplays but will not activate.
Any ideas what I have missed?
Without seeing your MXML Code, it's tough to compare your two approaches, but I believe #al_Birdy addressed the problem. You've created a custom ToggleSwitchSkin; not a custom ToggleSwitch.
Modify your addToggle() method like this:
public function addToggle():void {
var myCustomToggle:MyToggleSwitch = new MyToggleSwitch();
myCustomToggle.setStyle('skinClass',skins.MyToggleSwitchSkin);
hgroup.addElement(myCustomToggle);
}
I suspect you'll have better luck.

AS3 [Event(name="", type="")], what is the significance?

I develop with FlashDevelop3 R2 and the Flex 3.3 SDK and there are many occasions where I must use the embed metadata tag as such:
[Embed(source="path/to/file")]
private var Asset:Class;
I understand the above all well and good, and I am thankful it exists because I do not like to open the flash IDE too often.
When I am going through other authors classes lately, I have found an interesting metadata tag that I do not understand:
[Event(name="", type="")]
I have yet to see a situation where I require this, and furthermore I really just do not understand what it is for.
Thank in advance for your help.
Brian Hodgeblog.hodgedev.com hodgedev.com
These [Event(name, type)] declarations describe which events a class instance is likely to dispatch.
They are actually useful for code completion - for instance when you type: mySprite.addEventListener(, your code editor (Flex Builder or FlashDevelop) will display a meaningful list of events that this object can dispatch.
So you can add these declarations in your code and benefit from a richer code completion.
Also note that this works with custom Event classes (see FlashDevelop's new Event class template).
package mycomp {
import flash.events.Event;
public class MyEvent extends Event {
public const SOME_EVENT:String = "someEvent";
// required Event type declarations
}
}
package mycomp {
[Event(name="someEvent", type="mycomp.MyEvent")]
public class MyComp extends Sprite {
}
}
package myproject {
import mycomp.MyComp;
public class MyProject {
function MyProject() {
var mc:MyComp = new MyComp();
mc.addEventLister( //completes: SOME_EVENT + Sprite events
}
}
}
We use it for binding custom events to our custom MXML components. This tag allows you to reference it from MXML. See documentation:
[Event(name="enableChanged", type="flash.events.Event")]
class ModalText extends TextArea {
...
}
<MyComp:ModalText enableChanged="handleEnableChangeEvent(event);"/>
The compiler will complain, however, if you try to refer to an event on an mxml tag that was not declared with an event metatag.