Skip to content

Commit

Permalink
Merge pull request #11425 from emberjs/fix-container-view-hooks
Browse files Browse the repository at this point in the history
Fix container view hooks
  • Loading branch information
rwjblue committed Jun 12, 2015
2 parents f6d5b42 + 177733b commit 4ec788b
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import run from 'ember-metal/run_loop';
import Component from 'ember-views/views/component';
import compile from 'ember-template-compiler/system/compile';
import { runAppend, runDestroy } from "ember-runtime/tests/utils";

import { set } from 'ember-metal/property_set';

var component;

QUnit.module('ember-htmlbars: destroy-element-hook tests', {
teardown() {
runDestroy(component);
}
});

QUnit.test('willDestroyElement is only called once when a component leaves scope', function(assert) {
var innerChild, innerChildDestroyed;

component = Component.create({
switch: true,

layout: compile(`
{{~#if switch~}}
{{~#view innerChild}}Truthy{{/view~}}
{{~/if~}}
`),

innerChild: Component.extend({
init() {
this._super(...arguments);
innerChild = this;
},

willDestroyElement() {
if (innerChildDestroyed) {
throw new Error('willDestroyElement has already been called!!');
} else {
innerChildDestroyed = true;
}
}
})
});

runAppend(component);

assert.equal(component.$().text(), 'Truthy', 'precond - truthy template is displayed');
assert.equal(component.get('childViews.length'), 1);

run(function() {
set(component, 'switch', false);
});

run(function() {
assert.equal(innerChild.get('isDestroyed'), true, 'the innerChild has been destroyed');
assert.equal(component.$().text(), '', 'truthy template is removed');
});
});
16 changes: 3 additions & 13 deletions packages/ember-metal-views/lib/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,7 @@ Renderer.prototype.willDestroyElement = function (view) {
}

if (view._transitionTo) {
view._transitionTo('destroying', false);
}

var childViews = view.childViews;
if (childViews) {
for (var i = 0; i < childViews.length; i++) {
this.willDestroyElement(childViews[i]);
}
view._transitionTo('destroying');
}
};

Expand All @@ -253,11 +246,8 @@ Renderer.prototype.didDestroyElement = function (view) {
view._transitionTo('preRender');
}

var childViews = view.childViews;
if (childViews) {
for (var i = 0; i < childViews.length; i++) {
this.didDestroyElement(childViews[i]);
}
if (view.trigger) {
view.trigger('didDestroyElement');
}
}; // element destroyed so view.destroy shouldn't try to remove it removedFromDOM

Expand Down
6 changes: 3 additions & 3 deletions packages/ember-views/lib/mixins/view_state_support.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import Ember from 'ember-metal/core';
import { Mixin } from "ember-metal/mixin";

var ViewStateSupport = Mixin.create({
transitionTo(state, children) {
transitionTo(state) {
Ember.deprecate("Ember.View#transitionTo has been deprecated, it is for internal use only");
this._transitionTo(state, children);
this._transitionTo(state);
},

_transitionTo(state, children) {
_transitionTo(state) {
var priorState = this.currentState;
var currentState = this.currentState = this._states[state];
this._state = state;
Expand Down
23 changes: 21 additions & 2 deletions packages/ember-views/lib/views/container_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
observer,
beforeObserver
} from "ember-metal/mixin";
import { on } from "ember-metal/events";

import containerViewTemplate from "ember-htmlbars/templates/container-view";
containerViewTemplate.meta.revision = 'Ember@VERSION_STRING_PLACEHOLDER';
Expand Down Expand Up @@ -280,8 +281,26 @@ var ContainerView = View.extend(MutableArray, {
},

objectAt(idx) {
return get(this, 'childViews')[idx];
}
return this.childViews[idx];
},

_triggerChildWillDestroyElement: on('willDestroyElement', function () {
var childViews = this.childViews;
if (childViews) {
for (var i = 0; i < childViews.length; i++) {
this.renderer.willDestroyElement(childViews[i]);
}
}
}),

_triggerChildDidDestroyElement: on('didDestroyElement', function () {
var childViews = this.childViews;
if (childViews) {
for (var i = 0; i < childViews.length; i++) {
this.renderer.didDestroyElement(childViews[i]);
}
}
})
});

export default ContainerView;

0 comments on commit 4ec788b

Please sign in to comment.