Reputation: 34138
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.
Upvotes: 3
Views: 2970
Reputation: 15276
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')
});
Upvotes: 3