Reputation: 28790
Previously I had my own custom link-to
helper that I blogged about here.
With handlebars I could pass arguments that would cause a re-render if the value changed, for example if I am binding to model that has isLoaded=false
, then the LinkView
view would re-render when isLoaded=true
or the value changed from undefined to its value.
Below is my old handlebars custom link-to helper
Ember.Handlebars.registerHelper('resource-link-to', function(path, options) {
var args = Array.prototype.slice.call(arguments, 1);
var resource = this.get(path);
var resourceRoute = resource.humanize();
if (!options.fn) {
options.types = ['STRING', 'STRING', 'ID'];
options.contexts = [this, this, this];
args.unshift(path);
args.unshift(resourceRoute);
args.unshift(resource.get('displayName'));
} else {
options.types = ['STRING', 'ID'];
options.contexts = [this, this];
args.unshift(path);
args.unshift(resourceRoute);
}
return Ember.Handlebars.helpers['link-to'].apply(this, args);
});
The ID
marker in this line meant it was a binding:
options.types = ['STRING', 'STRING', 'ID'];
I am trying to replicate this in htmlbars in ember 1.13.11
and I have extendted the LinkComponent
and overriden willRender
like this:
export default LinkComponent.extend({
willRender() {
// FIXME: allow for css classes and query params
Ember.assert('you must specify a resource', this.attrs.resource);
const resource = this.attrs.resource;
let resourceRoute = resource.value.humanize();
if(typeToLinks[resourceRoute]) {
resourceRoute = typeToLinks[resourceRoute];
}
this.set('attrs', {
params: [resource.value.get('displayName'), resourceRoute, resource],
view: this.parentView,
hasBlock: false,
escaped: true
});
this._super(...arguments);
}
});
I then call it like this:
{{resource-linkto resource=activity.reference}}
The problem is that the resource
might be in an isLoaded=false
state as it is partially resolved.
How can I trigger a re-render when the value is resolved like I used to do in handlebars?
Upvotes: 2
Views: 117
Reputation: 35491
Well, I cannot really see how you are leveraging the isLoaded
flag in your first example. Please add a comment on the following solution to correct me if I misunderstood you in any way.
How can I trigger a re-render when the value is resolved like I used to do in handlebars?
This would probably be the easiest to solve by using an observer on the isLoaded
property of the resource
and call rerender()
when the property changes:
export default LinkComponent.extend({
// isLoaded: Ember.computed.alias('resource.isLoaded') // OR you can create this alias and use `isLoaded` instead of `resource.isLoaded` throughout your code
// rerender the component when the resource isLoaded becomes true
onResourceLoaded: Ember.observer('resource.isLoaded', function() {
if(this.get('resource.isLoaded')) {
this.rerender();
}
}
willRender() {
// ...
}
}
NOTE
The code within willRender
will be called again after calling rerender()
.
If you need that code to execute only once, you can use the following component hooks instead of willRender
:
didInsertElement
if you want code to run the first time the element is inserted in the DOM.
didInitAttrs
if you want code to run after a component was created and passed attrs
are guaranteed to be present.
Upvotes: 1