Skip to content

Commit

Permalink
Merge pull request #11231 from rwjblue/fix-legacy-each-else-block
Browse files Browse the repository at this point in the history
[BUGFIX beta] Fix {{each}} with `itemViewClass` and {{else}}.
  • Loading branch information
rwjblue committed May 20, 2015
2 parents d5a4719 + 6c2f000 commit afe178f
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 50 deletions.
2 changes: 1 addition & 1 deletion packages/ember-htmlbars/lib/templates/legacy-each.hbs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{{~#each view._arrangedContent as |item|}}{{#if attrs.itemViewClass}}{{#view attrs.itemViewClass controller=item _defaultTagName=view._itemTagName}}{{legacy-yield item}}{{/view}}{{else}}{{legacy-yield item controller=item}}{{/if}}{{else if attrs.emptyViewClass}}{{view attrs.emptyViewClass _defaultTagName=view._itemTagName}}{{/each~}}
{{~#each view._arrangedContent as |item|}}{{#if attrs.itemViewClass}}{{#view attrs.itemViewClass controller=item _defaultTagName=view._itemTagName}}{{legacy-yield item}}{{/view}}{{else}}{{legacy-yield item controller=item}}{{/if}}{{else if view._emptyView}}{{view view._emptyView _defaultTagName=view._itemTagName}}{{/each~}}
19 changes: 19 additions & 0 deletions packages/ember-htmlbars/tests/helpers/each_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,25 @@ QUnit.test("it supports {{itemViewClass=}} with tagName in itemViewClass (DEPREC
equal(view.$('ul li').text(), 'Steve HoltAnnabelle');
});

QUnit.test("it supports {{itemViewClass=}} with {{else}} block (DEPRECATED)", function() {
runDestroy(view);

view = EmberView.create({
template: templateFor(`
{{~#each view.people itemViewClass="my-view" as |item|~}}
{{item.name}}
{{~else~}}
No records!
{{~/each}}`),
people: A(),
container: container
});

runAppend(view);

equal(view.$().text(), 'No records!');
});

QUnit.test("it supports {{itemViewClass=}} with in format", function() {
MyView = EmberView.extend({
template: templateFor("{{person.name}}")
Expand Down
62 changes: 62 additions & 0 deletions packages/ember-views/lib/mixins/empty_view_support.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
@module ember
@submodule ember-views
*/

import { Mixin } from "ember-metal/mixin";
import View from "ember-views/views/view";
import { get } from "ember-metal/property_get";
import { set } from "ember-metal/property_set";
import { computed } from "ember-metal/computed";

/**
@class EmptyViewSupport
@namespace Ember
*/
export default Mixin.create({
/**
This provides metadata about what kind of empty view class this
collection would like if it is being instantiated from another
system (like Handlebars)
@private
@property emptyViewClass
*/
emptyViewClass: View,

/**
An optional view to display if content is set to an empty array.
@property emptyView
@type Ember.View
@default null
*/
emptyView: null,

_emptyView: computed('emptyView', 'attrs.emptyViewClass', 'emptyViewClass', function() {
var emptyView = get(this, 'emptyView');
var attrsEmptyViewClass = this.getAttr('emptyViewClass');
var emptyViewClass = get(this, 'emptyViewClass');
var inverse = get(this, '_itemViewInverse');
var actualEmpty = emptyView || attrsEmptyViewClass;

// Somehow, our previous semantics differed depending on whether the
// `emptyViewClass` was provided on the JavaScript class or via the
// Handlebars template.
// In Glimmer, we disambiguate between the two by checking first (and
// preferring) the attrs-supplied class.
// If not present, we fall back to the class's `emptyViewClass`, but only
// if an inverse has been provided via an `{{else}}`.
if (inverse && actualEmpty) {
if (actualEmpty.extend) {
return actualEmpty.extend({ template: inverse });
} else {
set(actualEmpty, 'template', inverse);
}
} else if (inverse && emptyViewClass) {
return emptyViewClass.extend({ template: inverse });
}

return actualEmpty;
})
});
51 changes: 3 additions & 48 deletions packages/ember-views/lib/views/collection_view.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/**
@module ember
@submodule ember-views
Expand All @@ -17,6 +16,7 @@ import {
beforeObserver
} from "ember-metal/mixin";
import { readViewFactory } from "ember-views/streams/utils";
import EmptyViewSupport from "ember-views/mixins/empty_view_support";

/**
`Ember.CollectionView` is an `Ember.View` descendent responsible for managing
Expand Down Expand Up @@ -179,9 +179,10 @@ import { readViewFactory } from "ember-views/streams/utils";
@class CollectionView
@namespace Ember
@extends Ember.ContainerView
@uses Ember.EmptyViewSupport
@since Ember 0.9
*/
var CollectionView = ContainerView.extend({
var CollectionView = ContainerView.extend(EmptyViewSupport, {

/**
A list of items to be displayed by the `Ember.CollectionView`.
Expand All @@ -192,25 +193,6 @@ var CollectionView = ContainerView.extend({
*/
content: null,

/**
This provides metadata about what kind of empty view class this
collection would like if it is being instantiated from another
system (like Handlebars)
@private
@property emptyViewClass
*/
emptyViewClass: View,

/**
An optional view to display if content is set to an empty array.
@property emptyView
@type Ember.View
@default null
*/
emptyView: null,

/**
@property itemViewClass
@type Ember.View
Expand Down Expand Up @@ -398,33 +380,6 @@ var CollectionView = ContainerView.extend({
}
},

_emptyView: computed('emptyView', 'attrs.emptyViewClass', 'emptyViewClass', function() {
var emptyView = get(this, 'emptyView');
var attrsEmptyViewClass = this.getAttr('emptyViewClass');
var emptyViewClass = get(this, 'emptyViewClass');
var inverse = get(this, '_itemViewInverse');
var actualEmpty = emptyView || attrsEmptyViewClass;

// Somehow, our previous semantics differed depending on whether the
// `emptyViewClass` was provided on the JavaScript class or via the
// Handlebars template.
// In Glimmer, we disambiguate between the two by checking first (and
// preferring) the attrs-supplied class.
// If not present, we fall back to the class's `emptyViewClass`, but only
// if an inverse has been provided via an `{{else}}`.
if (inverse && actualEmpty) {
if (actualEmpty.extend) {
return actualEmpty.extend({ template: inverse });
} else {
set(actualEmpty, 'template', inverse);
}
} else if (inverse && emptyViewClass) {
return emptyViewClass.extend({ template: inverse });
}

return actualEmpty;
}),

_emptyViewTagName: computed('tagName', function() {
var tagName = get(this, 'tagName');
return CollectionView.CONTAINER_MAP[tagName] || 'div';
Expand Down
3 changes: 2 additions & 1 deletion packages/ember-views/lib/views/legacy_each_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { set } from "ember-metal/property_set";
import { computed } from "ember-metal/computed";
import View from "ember-views/views/view";
import { CONTAINER_MAP } from "ember-views/views/collection_view";
import EmptyViewSupport from "ember-views/mixins/empty_view_support";

export default View.extend({
export default View.extend(EmptyViewSupport, {
template: legacyEachTemplate,
tagName: '',

Expand Down

0 comments on commit afe178f

Please sign in to comment.