Skip to content

Instantly share code, notes, and snippets.

@jelhan
Last active August 3, 2020 09:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jelhan/6bc9208e08122f5a43556eb514506912 to your computer and use it in GitHub Desktop.
Save jelhan/6bc9208e08122f5a43556eb514506912 to your computer and use it in GitHub Desktop.
ember sets value as a property
import Controller from '@ember/controller';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
class MyCustomElement extends HTMLElement {
connectedCallback() {
console.log('connectedCallback of custom element');
console.log('this.hasAttribute("foo")', this.hasAttribute('foo'));
console.log('this.getAttribute("foo")', this.getAttribute('foo'));
}
attributeChangedCallback() {
console.log('attributeChangedCallback of custom element');
console.log('this.hasAttribute("foo")', this.hasAttribute('foo'));
console.log('this.getAttribute("foo")', this.getAttribute('foo'));
}
disconnectedCallback() {
console.log('disconnectedCallback of custom element');
}
get foo() {
// Glimmer VM will set 'foo' as a property and not as an attribute
// if this property exists
}
static get observedAttributes() {
return ['foo'];
}
}
export default class ApplicationController extends Controller {
@tracked value = 'bar';
constructor() {
super(...arguments);
customElements.define('my-custom-element', MyCustomElement);
}
@action
changeValue() {
this.value = this.value === 'bar' ? 'baz' : 'bar';
}
}
import Helper from '@ember/component/helper';
export default class extends Helper {
element = null;
compute([tagName], attributes) {
if (this.element === null) {
this.element = document.createElement(tagName);
}
let { element } = this;
for (let attr in attributes) {
let value = attributes[attr];
element.setAttribute(attr, value);
}
return element;
}
}
import { helper } from '@ember/component/helper';
export default helper(function myHelper([tagName], attributes) {
let el = document.createElement(tagName);
for (let attr in attributes) {
let value = attributes[attr];
el.setAttribute(attr, value);
}
return el;
});
import Modifier from 'ember-modifier';
export default class OnModifier extends Modifier {
didInstall() {
console.log('didInstall hook of class based modifier');
}
didReceiveArguments() {
console.log('didReceiveArguments hook of class based modifier');
}
}
import { modifier } from 'ember-modifier';
export default modifier((element, [eventName, handler]) => {
console.log('functional modifier runs');
});
{{!--
If the value is a static string it does not throw
It seems as if a static string is always set as an
attribute.
<my-custom-element foo="bar"></my-custom-element>
--}}
{{!--
As soon as it's a dynamic value Glimmer VM tries
to set it as a property, which throws.
{{#let "bar" as |value|}}
<my-custom-element foo={{value}}></my-custom-element>
{{/let}}
--}}
{{!--
Functional modifier and hooks of class based
modifiers are executed after connectedCallback
of custom element.
<my-custom-element {{my-functional-modifier}} {{my-class-based-modifier}}></my-custom-element>
--}}
{{!--
Using a helper, which creates an element, sets
the attributes on it and returns it.
This works fine on inital rendering but causes
the custom element to be destroyed when ever a
value changes.
{{#let (create-element "my-custom-element" foo=this.value) as |Element|}}
{{Element}}
{{/let}}
--}}
<button {{on "click" this.changeValue}}>change value</button>
{{!--
Using a helper, which does the same as above
but reuses the same element and only updates
the attributes when input changes.
--}}
{{#let (create-element-cached "my-custom-element" foo=this.value) as |Element|}}
{{Element}}
{{/let}}
{
"version": "0.17.1",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js",
"ember": "3.18.1",
"ember-template-compiler": "3.18.1",
"ember-testing": "3.18.1"
},
"addons": {
"@glimmer/component": "1.0.0",
"ember-modifier": "2.1.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment