This addon created as rethinking of ember-ref-modifier, with simplified api and without cons of previous implementation.
Allow users get acces to DOM nodes inside component, including wrapping & destroying logic.
Simple, use case will look like:
- applying
ref
modifier with passed name to an element.
- have access to it inside component class as decorated property.
import Component from '@glimmer/component';
import { ref } from 'ember-ref-bucket';
export default class MyComponent extends Component {
@ref("FavouriteNode") node;
// this.node === "<div>hello</div>"
}
API differences, comparing to ember-ref-modifier
:
In ember-ref-modifier
ref modifier accept 2 positional arguments {{ref this "property"}}
:
- context to set path (
this
) - path to set on context (
"property"
)
In ember-ref-bucket
ref modifier accept 1 positional argument {{create-ref "field"}}
:
- reference name (
"field"
)
reference name should be passed as argument for @ref("field")
decorator, to allow it find reference by name.
- Ember.js v3.12 or above
- Ember CLI v2.13 or above
- Node.js v10 or above
ember install ember-ref-bucket
import Component from '@glimmer/component';
import { ref } from 'ember-ref-bucket';
import { action } from '@ember/object';
export class Player extends Component {
@ref('player') audioNode;
@action onPlay() {
this.audioNode.play()
}
}
import Component from '@glimmer/component';
import { ref } from 'ember-ref-bucket';
export default class MyComponent extends Component {
@ref("field") node = null;
}
This method will be very useful if we want to wrap node into some library and control it's lifecycle.
import Component from '@glimmer/component';
import { ref, registerNodeDestructor } from 'ember-ref-bucket';
class NodeWrapper {
constructor(node) {
this.node = node;
}
destroy() {
this.node = null;
}
value() {
return this.node.textContent;
}
}
export default class WrappedNodeComponent extends Component {
@ref('field', (node) => {
const instance = new NodeWrapper(node);
registerNodeDestructor(node, () => instance.destroy());
return instance;
}) node = null;
get value() {
return this.node?.value();
}
}
import { ref, globalRef, trackedRef, trackedGlobalRef } from 'ember-ref-bucket';
/*
ref - usage: @ref('foo', nodeWrapFn?), ref to bucket with current component context
globalRef - usage: @globalRef('foo', nodeWrapFn?), ref to global context (app)
trackedRef - usage: @trackedRef('foo', nodeWrapFn?), tracked ref to local context
trackedGlobalRef - usage: @trackedGlobalRef('foo', nodeWrapFn?), tracked ref to global context (app)
*/
import { registerNodeDestructor, unregisterNodeDestructor } from 'ember-ref-bucket';
/*
registerNodeDestructor(node, fn) - to assign any ref-node destructor
unregisterNodeDestructor(node, fn) - to remove assigned ref-node destructor
usage will be like:
@ref('field', (node) => {
const item = new InputMask(node);
registerNodeDestructor(node, () => item.destroy());
return item;
});
*/
/*
nodeFor - functional low-level primitive to get node access
*/
import { nodeFor } from 'ember-ref-bucket';
const domNode = nodeFor(this, 'field');
-
If you use dom node if
@tracked
chain calculations, you should use tracked ref. -
If you don't need to rerun tracked chain (for example, you use ref only for some event-based dom access), you should not use tracked ref.
- If you need to watch for node changes (resize, content, attributes), you can use tracked modifier, it will add resize observer and mutation observer into according element and will mark property as "dirty" for any mutation
- If you need to recalculate helper if some dome node changes (size, children, attributes), you need to use
tracked-ref-to
helper. - If you don't need it (you need to just have ref to dom node), you should choose
ref-to
helper.
create-ref
modifier andref-to
helper will not work in template-only components (because of no context), you should usecreate-global-ref
andglobal-ref-to
instead. Or providebucket
param tocreate-ref
modifier / helper.
Addon provide only 1 modifier (create-ref
) and 1 helper (ref-to
), other names will be transformed as described in tables:
Invocation | Will be transformed to |
---|---|
{{create-ref "foo"}} |
{{create-ref "foo" bucket=this}} |
{{create-tracked-ref "foo"}} |
{{create-ref "foo" bucket=this tracked=true}} |
{{create-global-ref "foo"}} |
{{create-ref "foo" bucket=undefined}} |
{{create-tracked-global-ref "foo"}} |
{{create-ref "foo" bucket=undefined tracked=true}} |
Invocation | Will be transformed to |
---|---|
{{ref-to "foo"}} |
{{ref-to "foo" bucket=this}} |
{{tracked-ref-to "foo"}} |
{{ref-to "foo" bucket=this tracked=true}} |
{{global-ref-to "foo"}} |
{{ref-to "foo" bucket=undefined}} |
{{tracked-global-ref-to "foo"}} |
{{ref-to "foo" bucket=undefined tracked=true}} |
See the Contributing guide for details.
This project is licensed under the MIT License.