glimmerjs / glimmer-component Goto Github PK
View Code? Open in Web Editor NEW[MOVED] This package is now part of the Glimmer.js monorepo
Home Page: https://github.com/glimmerjs/glimmer.js
[MOVED] This package is now part of the Glimmer.js monorepo
Home Page: https://github.com/glimmerjs/glimmer.js
A reproduction appropriate for http://glimmer-playground.netlify.com/.
import Component, { tracked } from '@glimmer/component';
class Service {
@tracked
isMax = false;
constructor() {
setTimeout(() => {
this.isMax = true;
}, 2000);
}
}
export default class extends Component {
@tracked
service = new Service();
@tracked('service')
get isMax() {
return this.service.isMax;
}
}
Expected: After 2 seconds both flags swap to true
Actual: Only the {{service.isMax}}
changes to true
Replaces: glimmerjs/glimmer-application#87
Hi guys! Again, excited about glimmer components.
One of my frustrations though, is with the current computed property syntax:
@tracked('firstName', 'lastName')
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
I like the computed properties, and how it uses memoization to store result of the function call using the "tracked" params. The problem is, sometimes I find developers new to the ember equivalent called Ember.computed
doing one of these two things, causing bugs:
@tracked('firstName')
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
or this:
@tracked('firstName', 'lastName')
get fancyName() {
return `@${this.firstName}`;
}
I actually see this occasionally from new ember developers with Ember.computed()
. What I've always wanted, is for the dependent params to be passed into the function, helping prevent developers from incorrectly tracking the wrong params:
@tracked('firstName', 'lastName')
fullName(firstName, lastName) {
return `${firstName} ${lastName}`;
}
With some good decoration, couldn't this be turned into a getter?
function tracked(...args) {
return function(target, key, descriptor) {
const fn = descriptor.value;
return {
get() {
const fnArgs = args.map(arg => this[arg]);
return fn.apply(this, fnArgs);
}
};
};
}
Then, unless I am mistaken, this.fullName
should continue to work.
Obviously the example tracked decorator directly above doesn't do any memoization, which would change it slightly.
Thoughts?
I believe the sudden influx of errors is probably due to the fact that the @glimmer
declaration files were never properly resolved until now.
$ npm run build:tests
> @glimmer/[email protected] build:tests /Users/akusuma/workspace/opensource/glimmerjs/glimmer-component
> rm -rf tests && BROCCOLI_ENV=tests broccoli build tests
Build project: @glimmer/component
Build env: tests
Build path: /Users/akusuma/workspace/opensource/glimmerjs/glimmer-component
/node_modules/@glimmer/compiler/node_modules/@glimmer/syntax/lib/traversal/errors.ts(4,70): Cannot find name 'Option'.
/node_modules/@glimmer/compiler/node_modules/@glimmer/syntax/lib/traversal/traverse.ts(68,25): Argument of type 'NodeHandler<Node>' is not assignable to parameter of type 'EnterExitNodeHandler<Node>'.
Type 'NodeHandlerFunction<Node>' is not assignable to type 'EnterExitNodeHandler<Node>'.
Property 'enter' is missing in type 'NodeHandlerFunction<Node>'.
/node_modules/@glimmer/compiler/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/compiler/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/compiler/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/compiler/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/interfaces/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/interfaces/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/object-reference/node_modules/@glimmer/reference/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/object-reference/node_modules/@glimmer/reference/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/object-reference/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/object-reference/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/reference/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/reference/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/runtime/lib/compiled/opcodes/builder.ts(16,8): Cannot find module '../../environment/constants'.
/node_modules/@glimmer/runtime/lib/environment.ts(4,27): Cannot find module './environment/constants'.
/node_modules/@glimmer/runtime/lib/opcodes.ts(5,27): Cannot find module './environment/constants'.
/node_modules/@glimmer/runtime/lib/vm/append.ts(20,8): Cannot find module '../environment/constants'.
/node_modules/@glimmer/runtime/lib/vm/update.ts(21,27): Cannot find module '../environment/constants'.
/node_modules/@glimmer/runtime/node_modules/@glimmer/interfaces/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/runtime/node_modules/@glimmer/interfaces/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/runtime/node_modules/@glimmer/reference/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/runtime/node_modules/@glimmer/reference/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/runtime/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/runtime/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/runtime/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/runtime/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(3,27): Cannot find name 'WeakMap'.
/node_modules/@glimmer/wire-format/node_modules/@glimmer/util/lib/weakmap.ts(6,22): Cannot find name 'WeakMap'.
/src/component-definition.ts(9,22): Class 'ComponentDefinition' incorrectly extends base class 'ComponentDefinition<Component>'.
Types of property 'manager' are incompatible.
Type 'ComponentManager' is not assignable to type 'ComponentManager<Component>'.
Types of property 'prepareArgs' are incompatible.
Type '(definition: ComponentDefinition, args: any) => any' is not assignable to type '(definition: ComponentDefinition<Component>, args: IArguments, dynamicScope: DynamicScope) => IAr...'.
Types of parameters 'definition' and 'definition' are incompatible.
Type 'ComponentDefinition<Component>' is not assignable to type 'ComponentDefinition'.
/src/component-definition.ts(16,17): Argument of type 'ComponentManager' is not assignable to parameter of type 'ComponentManager<Component>'.
/src/component-layout-compiler.ts(17,35): Argument of type 'string' is not assignable to parameter of type 'SerializedTemplateWithLazyBlock<TemplateMeta>'.
/src/component-manager.ts(7,3): Module '"/node_modules/@glimmer/runtime/index"' has no exported member 'CompiledBlock'.
/src/component-manager.ts(10,3): Module '"/node_modules/@glimmer/runtime/index"' has no exported member 'EvaluatedArgs'.
/src/component-manager.ts(28,3): Type 'PrimitiveReference<string>' is not assignable to type 'VersionedPathReference<string>'.
Types of property 'get' are incompatible.
Type '(_key: string) => PrimitiveReference<Value>' is not assignable to type '(property: string) => VersionedPathReference<Opaque>'.
Type 'PrimitiveReference<Value>' is not assignable to type 'VersionedPathReference<Opaque>'.
Types of property 'tag' are incompatible.
Type 'TagWrapper<RevisionTag>' is not assignable to type 'TagWrapper<RevisionTag>'. Two different types with this name exist, but they are unrelated.
Types have separate declarations of a private property 'type'.
/src/component-manager.ts(31,22): Class 'ComponentManager' incorrectly implements interface 'ComponentManager<Component>'.
Types of property 'prepareArgs' are incompatible.
Type '(definition: ComponentDefinition, args: any) => any' is not assignable to type '(definition: ComponentDefinition<Component>, args: IArguments, dynamicScope: DynamicScope) => IAr...'.
Types of parameters 'definition' and 'definition' are incompatible.
Type 'ComponentDefinition<Component>' is not assignable to type 'ComponentDefinition'.
Types of property 'manager' are incompatible.
Type 'ComponentManager<Component>' is not assignable to type 'ComponentManager'.
Property 'env' is missing in type 'ComponentManager<Component>'.
/src/component-manager.ts(64,16): Property 'compiledLayouts' does not exist on type 'Environment'.
/src/component-manager.ts(72,5): Type 'RootReference<Component>' is not assignable to type 'VersionedPathReference<Opaque>'.
Types of property 'get' are incompatible.
Type '<U>(prop: string) => VersionedPathReference<U>' is not assignable to type '(property: string) => VersionedPathReference<Opaque>'.
Type 'VersionedPathReference<any>' is not assignable to type 'VersionedPathReference<Opaque>'.
Types of property 'get' are incompatible.
Type '(property: string) => VersionedPathReference<Opaque>' is not assignable to type '(property: string) => VersionedPathReference<Opaque>'. Two different types with this name exist, but they are unrelated.
Type 'VersionedPathReference<Opaque>' is not assignable to type 'VersionedPathReference<Opaque>'. Two different types with this name exist, but they are unrelated.
Types of property 'tag' are incompatible.
Type 'TagWrapper<RevisionTag>' is not assignable to type 'TagWrapper<RevisionTag>'. Two different types with this name exist, but they are unrelated.
Types have separate declarations of a private property 'type'.
/test/rendering-test.ts(38,36): Argument of type 'string' is not assignable to parameter of type 'SerializedTemplateWithLazyBlock<TemplateMeta>'.
/test/test-helpers/compiler.ts(9,55): Generic type 'PrecompileOptions<T>' requires 1 type argument(s).
/test/test-helpers/dynamic-scope.ts(12,22): Class 'DynamicScope' incorrectly implements interface 'DynamicScope'.
Types of property 'get' are incompatible.
Type '(key: string) => VersionedPathReference<Opaque>' is not assignable to type '(key: string) => VersionedPathReference<Opaque>'. Two different types with this name exist, but they are unrelated.
Type 'VersionedPathReference<Opaque>' is not assignable to type 'VersionedPathReference<Opaque>'. Two different types with this name exist, but they are unrelated.
Types of property 'get' are incompatible.
Type '(property: string) => VersionedPathReference<Opaque>' is not assignable to type '(property: string) => VersionedPathReference<Opaque>'. Two different types with this name exist, but they are unrelated.
Type 'VersionedPathReference<Opaque>' is not assignable to type 'VersionedPathReference<Opaque>'. Two different types with this name exist, but they are unrelated.
/test/test-helpers/environment.ts(2,3): Module '"/node_modules/@glimmer/runtime/index"' has no exported member 'CompiledBlock'.
/test/test-helpers/environment.ts(7,3): Module '"/node_modules/@glimmer/runtime/index"' has no exported member 'EvaluatedArgs'.
/test/test-helpers/environment.ts(57,22): Class 'Environment' incorrectly extends base class 'Environment'.
Types of property 'iterableFor' are incompatible.
Type '(ref: VersionedReference<Opaque>, args: any) => AbstractIterable<Opaque, Opaque, IterationItem<Op...' is not assignable to type '(reference: VersionedReference<Opaque>, key: string) => AbstractIterable<Opaque, Opaque, Iteratio...'.
Types of parameters 'ref' and 'reference' are incompatible.
Type 'VersionedReference<Opaque>' is not assignable to type 'VersionedReference<Opaque>'. Two different types with this name exist, but they are unrelated.
Types of property 'tag' are incompatible.
Type 'TagWrapper<RevisionTag>' is not assignable to type 'TagWrapper<RevisionTag>'. Two different types with this name exist, but they are unrelated.
/test/test-helpers/environment.ts(60,45): Type '{}' does not satisfy the constraint 'TemplateMeta'.
Property '"<template-meta>"' is missing in type '{}'.
/test/test-helpers/environment.ts(62,33): Namespace '"/node_modules/@glimmer/runtime/lib/dom/interfaces"' has no exported member 'HTMLAnchorElement'.
/test/test-helpers/environment.ts(74,90): Argument of type 'Document' is not assignable to parameter of type 'HTMLDocument'.
Property 'addEventListener' is missing in type 'Document'.
/test/test-helpers/environment.ts(79,50): Argument of type 'this' is not assignable to parameter of type 'Environment'.
Type 'Environment' is not assignable to type 'Environment'. Two different types with this name exist, but they are unrelated.
Types of property 'iterableFor' are incompatible.
Type '(ref: VersionedReference<Opaque>, args: any) => AbstractIterable<Opaque, Opaque, IterationItem<Op...' is not assignable to type '(reference: VersionedReference<Opaque>, key: string) => AbstractIterable<Opaque, Opaque, Iteratio...'.
/test/test-helpers/environment.ts(83,72): Namespace '"/node_modules/@glimmer/runtime/lib/dom/interfaces"' has no exported member 'HTMLAnchorElement'.
/test/test-helpers/environment.ts(179,5): Type 'Iterable' is not assignable to type 'AbstractIterable<Opaque, Opaque, IterationItem<Opaque, Opaque>, VersionedPathReference<Opaque>, V...'.
Types of property 'tag' are incompatible.
Type 'RevisionTag' is not assignable to type 'TagWrapper<RevisionTag>'.
/test/test-helpers/environment.ts(185,38): Argument of type 'this' is not assignable to parameter of type 'Environment'.
Type 'Environment' is not assignable to type 'Environment'. Two different types with this name exist, but they are unrelated.
/test/test-helpers/iterable.ts(91,22): Class 'Iterable' incorrectly implements interface 'AbstractIterable<Opaque, Opaque, IterationItem<Opaque, Opaque>, RootReference<Opaque>, RootRefere...'.
Types of property 'tag' are incompatible.
Type 'RevisionTag' is not assignable to type 'TagWrapper<RevisionTag>'.
Property 'type' is missing in type 'RevisionTag'.
/test/test-helpers/iterable.ts(91,106): Type 'RootReference<Opaque>' does not satisfy the constraint 'VersionedPathReference<Opaque>'.
Types of property 'get' are incompatible.
Type '<U>(prop: string) => VersionedPathReference<U>' is not assignable to type '(property: string) => VersionedPathReference<Opaque>'.
Type 'VersionedPathReference<any>' is not assignable to type 'VersionedPathReference<Opaque>'.
Referencing this.args.todo
and this.args.onEdit
in my component gives these type errors:
/src/ui/components/todo-item/component.ts(12,31): Property 'todo' does not exist on type 'object'.
/src/ui/components/todo-item/component.ts(17,15): Property 'onEdit' does not exist on type 'object'.
/src/ui/components/todo-item/component.ts(17,32): Property 'todo' does not exist on type 'object'.
Is there a more permissive type we can use for "bag of arbitrary properties"?
Hey, I was playing a bit with Glimmer today and thought I can make TodoMVC app using this lib.
Unfortunately there are some missing things that could be really helpful to get the job done.
For example @tracked
decorator seems to accept only flat nested properties. What about nested ones, @each
and so on?
In ember we can do something like:
export default Ember.Component.extend({
numOfCompletedTodos: Ember.computed('[email protected]', function() {
return get(this, 'todos').filterBy('completed', true).length;
}),
});
It would be nice if glimmer supports something similar:
export default class TodoApp extends Component {
@tracked todos: object[];
constructor(options) {
super(options);
this.todos = [{ name: 'a', completed: true }, { name: 'b', completed: false' }];
}
@tracked('[email protected]')
get numOfCompletedTodos() {
return this.todos.filter(todo => todo.completed).length;
}
}
I don't see a way around at this moment. Do you?
Actually I could hack this by using this.todos = this.todos.slice(0);
and leaving @tracked('todos')
as is, but doing so I would feel really bad and I know it would be absolutely not acceptable.
Symbol object is used here
https://github.com/glimmerjs/glimmer-component/blob/master/src/tracked.ts#L65
Which is not at all supported in IE: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol#Browser_compatibility
Maybe at least IE11 should be supported? It still has >3% global usage.
A simple each
loop doesn't seem to work.
{{#each list}}
<li>{{this}}</li>
{{/each}}
Repro commit to hello-glimmer
Uncaught Error: Must specify a key for #each
at Environment$$1.iterableFor (environment.js:175)
at lists.js:23
at AppendOpcodes.evaluate (opcodes.js:270)
at VM.execute (append.js:288)
at Object.render (template.js:116)
at App.render (application.js:87)
at App.boot (application.js:79)
at index.js:4
When I use async functions in my components I get reference error: can't find variable regeneratorRuntime
didInsertElement
(this.element
yet due to Glimmer bugdidRender
didUpdate
willDestroy
Rendering a component inside an {{#each}}
loop blows up. Sourcemaps are busted right now so I'm exactly sure what's going on, but I'll try to add more info.
Repro commit against hello-world
: asakusuma/hello-glimmer@07c7617
Uncaught TypeError: Cannot read property 'specifier' of undefined
at Environment$$1.getComponentDefinition (app.js:7213)
at Environment$$1.hasComponentDefinition (app.js:7208)
at RawInlineBlock.specializeComponent (app.js:5557)
at RawInlineBlock.scan (app.js:5543)
at app.js:3148
at Compilers.compile (app.js:3070)
at compileStatement (app.js:5414)
at UnwrappedBuilder.compile (app.js:5704)
at ComponentLayoutBuilder.compile (app.js:5594)
at compileLayout (app.js:5582)
Based on glimmerjs/glimmer-application#53, glimmerjs/glimmer-application#50, and glimmerjs/glimmer-application#43 there is a weird interaction with @tracked
and scheduling a re-render. I thought I could fix it in glimmerjs/glimmer-application#52, however @krisselden mentioned that we likely need to internalize the check for CURRENT
in Glimmer VM it's self. You simply cannot have @tracked
cause the re-render directly, and in stead you need to check to see if the transaction needs to start at all.
The didUpdate hook is invoked before the component is re-rendered into the DOM. Here is a repo to reproduce the issue: https://github.com/habdelra/glimmerjs-didUpdate-hook/
The component looks like this:
import Component, { tracked } from "@glimmer/component";
export default class GlimmerDidUpdateHook extends Component {
updated = false;
@tracked
foo: boolean = false;
didInsertElement() {
setTimeout(() => {
this.foo = true;
}, 2000);
}
didUpdate() {
if (!this.updated) { // to compensate for infinite rerender bug
this.updated = true;
console.log('this.foo is ', this.foo);
let fooElement = document.getElementById("foo");
if (!fooElement) {
console.log("Can't find foo");
}
}
}
}
the template looks like this:
Hello!
I have this test file. From #70 I assume the approach should work.
import { setupRenderingTest } from '@glimmer/test-helpers';
import hbs from '@glimmer/inline-precompile';
const { module, test } = QUnit;
module('Component: bar-chart', function(hooks) {
setupRenderingTest(hooks);
test('it renders with a message that no data is available', async function(assert) {
await this.render(hbs`<bar-chart />`);
assert.ok(this.containerElement.querySelector('p').innerText = 'No data available');
});
test('it renders an svg when data is available', async function(assert) {
this.data = {
"name": "display",
"children": [
{"name": "DirtySprite", "size": 8833},
{"name": "LineSprite", "size": 1732},
{"name": "RectSprite", "size": 3623},
{"name": "TextSprite", "size": 10066}
]
};
await this.render(hbs`<bar-chart @data={{data}} />`);
assert.ok(this.containerElement.querySelector('svg'));
});
});
I get this result.
ok 1 Firefox 54.0 - Component: bar-chart: it renders with a message that no data is available
not ok 2 Firefox 54.0 - Component: bar-chart: it renders an svg when data is available
---
actual: >
null
stack: >
@http://localhost:7357/index.js:1455:5
evaluate@http://localhost:7357/index.js:1310:9
next@http://localhost:7357/index.js:6530:13
next@http://localhost:7357/index.js:6568:16
render@http://localhost:7357/index.js:7787:22
boot@http://localhost:7357/index.js:7774:9
render@http://localhost:7357/index.js:7031:5
@http://localhost:7357/index.js:15404:19
__awaiter$1</<@http://localhost:7357/index.js:15380:15
__awaiter$1<@http://localhost:7357/index.js:15360:12
@http://localhost:7357/index.js:15399:16
message: >
Promise rejected during it renders an svg when data is available: expr is null
Log: |
...
ok 3 Chrome 60.0 - Component: bar-chart: it renders with a message that no data is available
not ok 4 Chrome 60.0 - Component: bar-chart: it renders an svg when data is available
---
actual: >
null
stack: >
TypeError: Cannot read property 'get' of null
at APPEND_OPCODES.add (http://localhost:7357/index.js:1455:23)
at AppendOpcodes.evaluate (http://localhost:7357/index.js:1310:9)
at VM.next (http://localhost:7357/index.js:6530:28)
at TemplateIterator.next (http://localhost:7357/index.js:6568:24)
at App$1.render (http://localhost:7357/index.js:7787:39)
at App$1.boot (http://localhost:7357/index.js:7774:14)
at Object.render (http://localhost:7357/index.js:7031:9)
at Object.<anonymous> (http://localhost:7357/index.js:15404:24)
at Generator.next (<anonymous>)
at http://localhost:7357/index.js:15380:71
message: >
Promise rejected during it renders an svg when data is available: Cannot read property 'get' of null
Log: |
...
1..4
# tests 4
# pass 2
# skip 0
# fail 2
I would like to debug what's going on but the browsers always close. I tried using an alert
to open up the dev tools and use the inline debugger
but this doesn't quite work. Also, Chrome crashed after a few reruns.
Any config option that can help me with this one?
I can't confirm if this works or not because of glimmerjs/glimmer-application#95 .
I tried adding a test that does more then check the top-most div and didn't find any documentation on how this would look like, so I assumed something similar to how this is done in Ember would work:
test('it renders an svg when data is available', async function(assert) {
this.data = {
"name": "display",
"children": [
{"name": "DirtySprite", "size": 8833},
{"name": "LineSprite", "size": 1732},
{"name": "RectSprite", "size": 3623},
{"name": "TextSprite", "size": 10066}
]
};
await this.render(hbs`<bar-chart @data={{data}} />`);
assert.ok(this.containerElement.querySelector('svg'));
});
Can you confirm?
I've run into a scenario where a property that tracks a field off of this.args
is not updating. I've setup a GH project to demonstrate this here: https://github.com/habdelra/glimmer-tracking-args.
To summarize I have a parent component that contains a child component, with a data binding as expressed in the template.
The parent component looks like this:
import Component, { tracked } from "@glimmer/component";
export default class GlimmerTrackingArgs extends Component {
@tracked
model: any = {
foo: "bar",
bleep: "blurp"
};
@tracked ("model")
get stringifiedModel() {
return JSON.stringify(this.model);
}
didInsertElement() {
setTimeout(() => {
this.model = {
...this.model,
foo: "bloop"
};
}, 1000);
}
}
the parent component template:
The child component has a tracked property that has a dependency on the passed in @model
, but it never seems to update:
import Component, { tracked } from "@glimmer/component";
export default class ChildComponent extends Component {
@tracked ("args.model.foo")
get foo() {
return this.args["model"].foo;
}
}
The child component template:
Steps to reproduce:
ember g glimmer-component parent-component
ember g glimmer-component parent-component/child-component
Put reference to child component in root/top level component instead of correctly in the parent-component.
This should generate error because as docs say:
Our new component then is only useable from inside our [parent template] file
Actual:
environment.ts:193 Uncaught Error: Could not find template for child-component
at Environment$$1.getComponentDefinition (environment.ts:193)
at Environment$$1.hasComponentDefinition (environment.ts:159)
at functions.js:226
at Compilers.compile (functions.js:45)
at compileStatement (scanner.js:17)
at compileStatements (scanner.js:68)
at CompilableTemplate.compileStatic (scanner.js:35)
at CompilableTemplate.compileDynamic (scanner.js:50)
at ComponentManager.layoutFor (component-manager.ts:111)
at component.js:144
This is simple example with only few components but imagine when you have hundreds and someone accidentally places component in the wrong location perhaps by mistakenly copy/pasting or something and now the whole app won't render.
The error message says it can't find the template which is misleading and not helpful for actually fixing the problem.
Brand new to glimmer so I don't know if this is possible, but it would be really nice if it was able to say something like this:
Expected:
Component <child-component /> in glimmer-test/template.hbs at line 9 was attempted to be rendered outside of it's parent components template: "parent-component/template.hbs"
This tells you what the actual problem is, where the offending component is and where it can be used.
For example, {{someArray.length}}
will produce the error
Uncaught TypeError: Cannot redefine property: length
Congratulations on launching an ambitious project. I'm listing here a few criticisms on your landing page that I hope you will take as constructive. As much effort as goes into projects like this, they deserve at least enough attention to get a fair shake from devs.
Suggestions for possible changes:
Best of luck going forward,
Lee
Btw, on a positive note you made front page of HN. :)
https://news.ycombinator.com/item?id=13979014
If an error is thrown in an action, nothing happens and nothing gets logged to the console.
The following files seem like they belong in the https://github.com/glimmerjs/glimmer-application repo instead:
I ran into a scenario where a modifying a tracked property was not triggering a rerender when set from within didInsertElement
. Note that when I wrap the property setting within a requestAnimationFrame
the re-render works. A sample github project demonstrating this issue is here: https://github.com/habdelra/glimmer-tracked-oddness
The component.ts looks like this:
import Component, { tracked } from "@glimmer/component";
export default class DemoComponent extends Component {
@tracked
foo: boolean = false;
didInsertElement() {
this.foo = true;
}
}
the corresponding template looks like this:
Hi, I'm having troubles running an app that i generated following the getting started guide, I'm running node v6.10.0, npm v3.10.0 and yarn v0.23.4 on a mac with macos sierra, i tried to google that error with no success, this is the trace:
Livereload server on http://localhost:49153
The Broccoli Plugin: [RollupWithDependencies] failed with:
Error: Could not resolve '@glimmer/local-debug-flags' from /Users/Wardrakus/projects/glimmer-start/node_modules/@glimmer/runtime/dist/modules/es2017/lib/opcodes.js
at Error (native)
at /Users/Wardrakus/projects/glimmer-start/node_modules/rollup-plugin-node-resolve/dist/rollup-plugin-node-resolve.cjs.js:85:23
at /Users/Wardrakus/projects/glimmer-start/node_modules/resolve/lib/async.js:50:13
at processDirs (/Users/Wardrakus/projects/glimmer-start/node_modules/resolve/lib/async.js:182:39)
at ondir (/Users/Wardrakus/projects/glimmer-start/node_modules/resolve/lib/async.js:197:13)
at load (/Users/Wardrakus/projects/glimmer-start/node_modules/resolve/lib/async.js:80:43)
at onex (/Users/Wardrakus/projects/glimmer-start/node_modules/resolve/lib/async.js:105:17)
at /Users/Wardrakus/projects/glimmer-start/node_modules/resolve/lib/async.js:26:73
at FSReqWrap.oncomplete (fs.js:123:15)
The broccoli plugin was instantiated at:
at RollupWithDependencies.Plugin (/Users/Wardrakus/projects/glimmer-start/node_modules/broccoli-plugin/index.js:7:31)
at RollupWithDependencies.Rollup (/Users/Wardrakus/projects/glimmer-start/node_modules/broccoli-rollup/dist/index.js:74:72)
at new RollupWithDependencies (/Users/Wardrakus/projects/glimmer-start/node_modules/@glimmer/application-pipeline/dist/lib/broccoli/rollup-with-dependencies.js:30:42)
at GlimmerApp.rollupTree (/Users/Wardrakus/projects/glimmer-start/node_modules/@glimmer/application-pipeline/dist/lib/broccoli/glimmer-app.js:252:16)
at GlimmerApp.package (/Users/Wardrakus/projects/glimmer-start/node_modules/@glimmer/application-pipeline/dist/lib/broccoli/glimmer-app.js:205:23)
at GlimmerApp.toTree (/Users/Wardrakus/projects/glimmer-start/node_modules/@glimmer/application-pipeline/dist/lib/broccoli/glimmer-app.js:232:28)
at module.exports (/Users/Wardrakus/projects/glimmer-start/ember-cli-build.js:23:14)
at Builder.setupBroccoliBuilder (/Users/Wardrakus/projects/glimmer-start/node_modules/ember-cli/lib/models/builder.js:56:19)
at new Builder (/Users/Wardrakus/projects/glimmer-start/node_modules/ember-cli/lib/models/builder.js:30:10)
at ServeTask.run (/Users/Wardrakus/projects/glimmer-start/node_modules/ember-cli/lib/tasks/serve.js:24:55)
Hope you can help me here, or point me to the correct direction.
Terrific job with this library btw.
This doesn't work:
<my-component @html={{{myHtml}}} />
But this does:
{{{myHtml}}}
Colleagues, I have a task to create a Glimmer.js component, say, <x-table/>
. This component should be exported as Web Component.
The goal is to create unified component that accepts data + config and render all the grid accordingly. Example of config:
[
{
heading:'Name',
sortable: true,
template: '{{givenName}} {{familyName}}'
},
{
heading:'Actions',
sortable: false,
template:'<a href="{{url}}" target="_blank">Learn more</a>'
}
]
Some of the columns contain mix of data and specific html.
This is how I provide data and config to the table:
<x-table @data={{ data }} @config={{config}}></x-table>
And this is template of the x-table component:
<table>
<tr>
{{#each @config.columns key="@index" as |column|}}
<th class="{{if column.sortable 'sortable'}}">{{column.heading}}</th>
{{/each}}
</tr>
{{#each @data key="@index" as |model|}}
<tr>
{{#each @config.columns key="@index" as |column|}}
<td>HOW CAN I RENDER TEMPLATE FROM CONFIG HERE?</td>
{{/each}}
</tr>
{{/each}}
</table>
I can't understand how to render dynamic templates. I tried <td>{{partial column.template}}</td>
, but the helper requires pre-registered template. I can't find any API how to do this.
Please advise how can I resolve the issue.
IMO
Counting on the fact we address markup in the configuration, as for me, then the solution should look something like this:
<x-table @data={{ data }}>
<column heading="Name" sortable>{{givenName}} {{familyName}}</column>
<column heading="Actions"><a href="{{url}}" target="_blank">Learn more</a></column>
</x-table>
But Glimmer.js does not have any API to access children components and read the data.
Similar solutions in different component libraries:
It is still open question how to pass the data as object in Web Component but at least question of configuration might be solved in this way for current example.
After figuring it out it makes sense that
<div>
{{#if dataIsAvailable}}
<svg></svg>
{{else}}
<p>No data available</p>
{{/if}}
</div>
would work, while this
{{#if dataIsAvailable}}
<svg></svg>
{{else}}
<p>No data available</p>
{{/if}}
would not.
The error message is Uncaught TypeError: expr.get is not a function
and you can figure it out eventually because the stack contains some references to OPCODES. However, as a newcomer, I failed to see any reference of this requirement in the docs.
While attempting to follow along with the glimmerjs guides, @rondale-sc and I had some difficulty using @tracked('args')
to create a derived computed property in a child component.
The guides suggest using the following to create a child component that has a computed property multiplied
that updates when its args.number
changes:
import Component from '@glimmer/component';
export default class MultiplyByTwo extends Component {
@tracked('args')
get multiplied() {
return this.args.number * 2;
}
}
This seems to work as expected in the glimmer-playground (which appears to use @glimmer/component
version 0.5.0). This is a link to a working version (with code lightly adapted from the code from the guides): http://bit.ly/2syFV7c
However, in a new glimmer app (created using ember cli with the @glimmer/blueprint
blueprint), using @glimmer/application
v0.7.2 and @glimmer/component
v0.6.0, the same code doesn't work correctly. Clicking the buttons updates the property shown in the template, but not the derived multiplied
property.
Here is a link to a commit from the app that exhibits this issue:
bantic/bodega-glimmer-test@f296b4f
Expected behavior: Clicking "number: 2" immediately changes the template to display "multiply: 4 (@Number: 2)".
Actual behavior: On the first click, the @number
text updates (to "@number: 2"
), but the "multiply" text does not (i.e. `"multiply: 2 (@Number: 2)"). Clicking the same button a second time causes the template to display the expected output.
It is possible to create a fragment component manager, register it, and use it with the {{use-component-manager
pragma (which is behind a feature flag). Do we want to ship a fragment component manager in this package? Or do we want to support fragments in a different way? Or do we just want to say "do it yourself" (which I am fine with)?
I just feel like this is an ultra-hidden feature we might want to give more exposure to in one way or another since it is not insignificant. Here are a couple real-world use cases off the top of my head: 1) rendering into the shadow dom of a custom element; 2) higher-order components.
First off, love the work put towards glimmer.
Just playing around with glimmer-components and I noticed that yields work, but they seem undocumented. Are block params currently supported? If so, what is their syntax? If not, is this a planned feature of the glimmer view layer? Is there any good workarounds to get a block param like feature if it isn't supported?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.