Use component prototypes instead of instances

This means the component instance is created in the template, meaning
properties can be overridden in the view helper. It also just makes
more sense - a view instance doesn’t need to exist until it is rendered
in the template.
This commit is contained in:
Toby Zerner 2015-02-26 09:43:53 +10:30
parent 12c4b60730
commit 8683025ef6
14 changed files with 43 additions and 33 deletions

View File

@ -16,7 +16,7 @@ export default ComposerBody.extend({
title: '',
populateControls: function(items) {
var title = Ember.Component.create({
var title = Ember.Component.extend({
tagName: 'h3',
layout: precompileTemplate('{{ui/text-input value=component.title class="form-control" placeholder=component.titlePlaceholder disabled=component.disabled autoGrow=true}}'),
component: this

View File

@ -15,7 +15,7 @@ export default ComposerBody.extend({
originalContent: Ember.computed.oneWay('post.content'),
populateControls: function(controls) {
var title = Ember.Component.create({
var title = Ember.Component.extend({
tagName: 'h3',
layout: precompileTemplate('Editing Post #{{component.post.number}} in <em>{{discussion.title}}</em>'),
discussion: this.get('post.discussion'),

View File

@ -12,7 +12,7 @@ export default ComposerBody.extend({
submitLabel: 'Post Reply',
populateControls: function(items) {
var title = Ember.Component.create({
var title = Ember.Component.extend({
tagName: 'h3',
layout: precompileTemplate('Replying to <em>{{component.discussion.title}}</em>'),
component: this

View File

@ -49,10 +49,10 @@ export default Ember.Component.extend(FadeIn, HasItemLists, UseComposer, {
populateHeader: function(items) {
var properties = this.getProperties('post');
items.pushObjectWithTag(PostHeaderUser.create(properties), 'user');
items.pushObjectWithTag(PostHeaderMeta.create(properties), 'meta');
items.pushObjectWithTag(PostHeaderEdited.create(properties), 'edited');
items.pushObjectWithTag(PostHeaderToggle.create(properties, {parent: this}), 'toggle');
items.pushObjectWithTag(PostHeaderUser.extend(properties), 'user');
items.pushObjectWithTag(PostHeaderMeta.extend(properties), 'meta');
items.pushObjectWithTag(PostHeaderEdited.extend(properties), 'edited');
items.pushObjectWithTag(PostHeaderToggle.extend(properties, {parent: this}), 'toggle');
},
savePost: function(post, data) {

View File

@ -64,7 +64,8 @@ export default Ember.Component.extend(FadeIn, HasItemLists, {
layoutName: 'components/index/discussion-info/terminal-post',
discussion: Ember.computed.alias('parent.discussion'),
displayLastPost: Ember.computed.alias('parent.displayLastPost'),
}).create({parent: this}), 'terminalPost');
parent: this
}), 'terminalPost');
},
actions: {

View File

@ -14,7 +14,7 @@ export default Ember.Component.extend({
return [];
}
items.forEach(function(item) {
item.set('isListItem', item.get('tagName') === 'li');
item.reopenClass({isListItem: item.proto().tagName === 'li'});
});
return items;
})

View File

@ -22,7 +22,7 @@ export default Ember.Component.extend(HasItemLists, {
},
populateControls: function(items) {
this.addActionItem(items, 'submit', this.get('submitLabel')).set('className', 'btn btn-primary');
this.addActionItem(items, 'submit', this.get('submitLabel')).reopen({className: 'btn btn-primary'});
},
actions: {

View File

@ -50,7 +50,7 @@ export default Ember.Controller.extend(Ember.Evented, UseComposerMixin, {
// Otherwise, we'll create an alert message to inform the user
// that their reply has been posted, containing a button which
// will transition to their new post when clicked.
var message = AlertMessage.create({
var message = AlertMessage.extend({
type: 'success',
message: 'Your reply was posted.',
buttons: [{

View File

@ -21,6 +21,7 @@ export default Ember.Mixin.create({
populateItemList: function(name) {
var items = TaggedArray.create();
this.trigger('populate'+name.charAt(0).toUpperCase()+name.slice(1), items);
this.removeUnneededSeparatorItems(items);
return items;
},
@ -36,18 +37,26 @@ export default Ember.Mixin.create({
}
});
var itemInstance = item.create();
items.pushObjectWithTag(item, tag);
items.pushObjectWithTag(itemInstance, tag);
return itemInstance;
return item;
},
addSeparatorItem: function(items) {
var length = items.get('length');
var last = items.objectAt(length - 1);
if (last && !(last instanceof SeparatorItem)) {
items.pushObject(SeparatorItem.create());
items.pushObject(SeparatorItem);
},
removeUnneededSeparatorItems: function(items) {
var prevItem = null;
items.forEach(function(item) {
if (prevItem === SeparatorItem && item === SeparatorItem) {
items.removeObject(item);
return;
}
prevItem = item;
});
if (prevItem === SeparatorItem) {
items.removeObject(prevItem);
}
}
});

View File

@ -27,7 +27,7 @@ export default Ember.Mixin.create({
showErrorsAsAlertMessages: function(errors) {
for (var i in errors) {
var message = AlertMessage.create({
var message = AlertMessage.extend({
type: 'warning',
message: errors[i]
});

View File

@ -60,7 +60,7 @@ export default Ember.View.extend(HasItemLists, {
populateHeaderSecondary: function(items) {
var controller = this.get('controller');
items.pushObjectWithTag(SearchInput.create({
items.pushObjectWithTag(SearchInput.extend({
placeholder: 'Search Forum',
controller: controller,
valueBinding: Ember.Binding.oneWay('controller.searchQuery'),
@ -69,7 +69,7 @@ export default Ember.View.extend(HasItemLists, {
}), 'search');
if (this.get('controller.session.isAuthenticated')) {
items.pushObjectWithTag(UserDropdown.create({
items.pushObjectWithTag(UserDropdown.extend({
user: this.get('controller.session.user'),
logout: function() { controller.send('invalidateSession'); }
}), 'user');
@ -81,7 +81,7 @@ export default Ember.View.extend(HasItemLists, {
populateFooterPrimary: function(items) {
var addStatistic = function(label, number) {
items.pushObjectWithTag(ForumStatistic.create({
items.pushObjectWithTag(ForumStatistic.extend({
label: label,
number: number
}), 'statistics.'+label);
@ -93,6 +93,6 @@ export default Ember.View.extend(HasItemLists, {
},
populateFooterSecondary: function(items) {
items.pushObjectWithTag(PoweredBy.create(), 'poweredBy');
items.pushObjectWithTag(PoweredBy, 'poweredBy');
}
});

View File

@ -233,7 +233,7 @@ export default Ember.View.extend(HasItemLists, {
populateControls: function(items) {
var view = this;
var addControl = function(tag, title, icon) {
view.addActionItem(items, tag, null, icon).set('className', 'btn btn-icon btn-link').set('title', title);
view.addActionItem(items, tag, null, icon).reopen({className: 'btn btn-icon btn-link', title: title});
};
if (this.get('fullscreen')) {

View File

@ -48,13 +48,13 @@ export default Ember.View.extend(HasItemLists, {
// ------------------------------------------------------------------------
populateSidebar: function(items) {
items.pushObjectWithTag(DropdownSplit.create({
items.pushObjectWithTag(DropdownSplit.extend({
items: this.populateItemList('controls'),
icon: 'reply',
buttonClass: 'btn-primary'
}), 'controls');
items.pushObjectWithTag(StreamScrubber.create({
items.pushObjectWithTag(StreamScrubber.extend({
streamContent: this.get('streamContent')
}), 'scrubber');
},

View File

@ -13,7 +13,7 @@ export default Ember.View.extend(HasItemLists, {
itemLists: ['sidebar'],
didInsertElement: function() {
this.set('hero', WelcomeHero.create({
this.set('hero', WelcomeHero.extend({
title: this.get('controller.controllers.application.forumTitle'),
description: 'Thanks for stopping by!'
}));
@ -73,26 +73,26 @@ export default Ember.View.extend(HasItemLists, {
}),
populateSidebar: function(items) {
this.addActionItem(items, 'newDiscussion', 'Start a Discussion', 'edit').set('className', 'btn btn-primary new-discussion');
this.addActionItem(items, 'newDiscussion', 'Start a Discussion', 'edit').reopen({className: 'btn btn-primary new-discussion'});
var nav = this.populateItemList('nav');
items.pushObjectWithTag(DropdownSelect.create({ items: nav }), 'nav');
items.pushObjectWithTag(DropdownSelect.extend({items: nav}), 'nav');
},
populateNav: function(items) {
items.pushObjectWithTag(NavItem.create({
items.pushObjectWithTag(NavItem.extend({
label: 'All Discussions',
icon: 'comments-o',
layout: precompileTemplate('{{#link-to "index" (query-params filter="")}}{{fa-icon icon}} {{label}} <span class="count">{{badge}}</span>{{/link-to}}')
}), 'all');
items.pushObjectWithTag(NavItem.create({
items.pushObjectWithTag(NavItem.extend({
label: 'Private',
icon: 'envelope-o',
layout: precompileTemplate('{{#link-to "index" (query-params filter="private")}}{{fa-icon icon}} {{label}} <span class="count">{{badge}}</span>{{/link-to}}')
}), 'private');
items.pushObjectWithTag(NavItem.create({
items.pushObjectWithTag(NavItem.extend({
label: 'Following',
icon: 'star',
layout: precompileTemplate('{{#link-to "index" (query-params filter="following")}}{{fa-icon icon}} {{label}} <span class="count">{{badge}}</span>{{/link-to}}')