Emberjs DefaultTo Computed Property
Posted By: Anonymous
Often, I want my views to default to a specific value if the actual model property is not set.
This placeholder text/value is strictly view only and hence, should not be placed in the model imo.
So, this is what I end up doing:
// Sample 'Model' for illustration purposes only.
var myModel = Ember.Object.extend({
title: null,
description: null,
thumbUrl: null
});
/**
* Sample View
* Render view properties which are actually
* computed of the actual 'content' properties
*/
var myView = Ember.View.extend({
template: Ember.Handlebars.compile('<p>Title: {{view.title}}</p> <p>Description: {{view.description}}</p> <p>Image: <img {{bindAttr src="view.thumbUrl"}}/></p>'),
title: function () {
return this.get('content.title') || 'Title goes here';// placeholder 'title' text
}.property('content.title'),
description: function () {
return this.get('content.description') || 'This is your description'; // placeholder 'description'
}.property('content.description'),
thumbUrl: function () {
return this.get('content.thumbUrl') || 'http://placehold.it/100x100';
}.property('content.thumbUrl')
});
Any suggestions on how can I reduce boilerplate on defining defaults on all those properties i.e. ‘title’, ‘description’ and ‘thumbUrl’ ?
I looked into Ember.computed.defaultTo but failed to understand on how I can use it. This is how I envision it in action:
var myView = Ember.View.extend({
template: Ember.Handlebars.compile('<p>Title: {{view.title}}</p> <p>Description: {{view.description}}</p> <p>Image: <img {{bindAttr src="view.thumbUrl"}}/></p>'),
title: Ember.computed.defaultTo('content.title', 'Title goes here'),
description: Ember.computed.defaultTo('content.description', 'This is your description'),
thumbUrl: Ember.computed.defaultTo('content.thumbUrl', 'http://placehold.it/100x100')
});
So how can this be done ?
If there are better approaches to do this type of a thing, I would like to hear them in the comments.
Also, pointers to what Ember.computed.defaultTo does would be really helpful as well.
Solution
This is not what Ember.computed.defaultTo
is intended to do. Ember.computed.defaultTo takes a single defaultPath
parameter. From the docs:
computed property which acts like a standard getter and setter, but defaults to the value from
defaultPath
.
If you read the test, it sheds some light.
testBoth('Ember.computed.defaultTo', function(get, set) {
var obj = { source: 'original source value' };
Ember.defineProperty(obj, 'copy', Ember.computed.defaultTo('source'));
equal(get(obj, 'copy'), 'original source value');
set(obj, 'copy', 'new copy value');
equal(get(obj, 'source'), 'original source value');
equal(get(obj, 'copy'), 'new copy value');
set(obj, 'source', 'new source value');
equal(get(obj, 'copy'), 'new copy value');
set(obj, 'copy', null);
equal(get(obj, 'copy'), 'new source value');
});
Instead, you could write your own helper like so:
Ember.computed.defaultValue = function(dependentKey, defaultValue) {
return Ember.computed(dependentKey, function() {
return Ember.get(this, dependentKey) || defaultValue;
});
};
var myView = Ember.View.extend({
template: Ember.Handlebars.compile('<p>Title: {{view.title}}</p> <p>Description: {{view.description}}</p> <p>Image: <img {{bindAttr src="view.thumbUrl"}}/></p>'),
title: Ember.computed.defaultValue('content.title', 'Title goes here'),
description: Ember.computed.defaultValue('content.description', 'This is your description'),
thumbUrl: Ember.computed.defaultValue('content.thumbUrl', 'http://placehold.it/100x100')
});
If you’d rather not create your own helper function, an alternative approach would be to use separate properties for default values and then use Ember.computed.any
.
var myView = Ember.View.extend({
template: Ember.Handlebars.compile('<p>Title: {{view.title}}</p> <p>Description: {{view.description}}</p> <p>Image: <img {{bindAttr src="view.thumbUrl"}}/></p>'),
defaultTitle: 'Title goes here',
title: Ember.computed.any('content.title', 'defaultTitle'),
defaultDescription: 'This is your description',
description: Ember.computed.any('content.description', 'defaultDescription'),
defaultThumbUrl: 'http://placehold.it/100x100',
thumbUrl: Ember.computed.any('content.thumbUrl', 'defaultThumbUrl')
});
Answered By: Anonymous
Disclaimer: This content is shared under creative common license cc-by-sa 3.0. It is generated from StackExchange Website Network.