New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container view hooks #1198

Merged
merged 1 commit into from Oct 15, 2012
Jump to file or symbol
Failed to load files and symbols.
+172 −10
Diff settings

Always

Just for now

@@ -230,6 +230,45 @@ var childViewsProperty = Ember.computed(function() {
{{view Ember.ContainerView currentViewBinding="App.appController.view"}}
```
## Use lifecycle hooks
This is an example of how you could implement reusable currentView view.
``` javascript
App.ContainerView = Ember.ContainerView.extend({
appendCurrentView: function(currentView, callback) {
currentView.set('isVisible', true);
if (!this.get('childViews').contains(currentView)) {
this._super(currentView, callback);
} else {
callback();
}
},
removeCurrentView: function(currentView, callback) {
if (currentView.get('isShared')) {
currentView.set('isVisible', false);
callback();
} else {
this._super(currentView, callback);
}
}
});
````
This is an example of how you could implement animations.
```` javascript
App.ContainerView = Ember.ContainerView.extend({
presentCurrentView: function(currentView, callback) {
currentView.$().animate({top: '0px'}, callback);
},
dismissCurrentView: function(currentView, callback) {
currentView.$().animate({top: '-100px'}, callback);
}
});
````
@class ContainerView
@namespace Ember
@extends Ember.View
@@ -259,9 +298,6 @@ Ember.ContainerView = Ember.View.extend({
_childViews[idx] = view;
}, this);
var currentView = get(this, 'currentView');
if (currentView) _childViews.push(this.createChildView(currentView));
// Make the _childViews array observable
Ember.A(_childViews);
@@ -272,6 +308,10 @@ Ember.ContainerView = Ember.View.extend({
willChange: 'childViewsWillChange',
didChange: 'childViewsDidChange'
});
// Make sure we initialize with currentView if it is present
var currentView = get(this, 'currentView');
if (currentView) { this._currentViewDidChange(); }
},
/**
@@ -370,22 +410,94 @@ Ember.ContainerView = Ember.View.extend({
currentView: null,
/**
This method is responsible for presenting a new view.
Default implementation will simply call the callback.
You can override this method if you want to add an animation for example.
@param {Ember.View} currentView a view to present
@param {Function} callback the callback called once operation is terminated
*/
presentCurrentView: function(currentView, callback) {
callback();
},
/**
This method is responsible for adding view to containerView
@param {Ember.View} currentView a view to present
@param {Function} callback the callback called once view is appended
*/
appendCurrentView: function(currentView, callback) {
var childViews = get(this, 'childViews');
currentView.one('didInsertElement', callback);
childViews.pushObject(currentView);
},
/**
This method is responsible for dismissing a view.
Default implementation will simply call the callback.
You can override this method if you want to add an animation for example.
@param {Ember.View} currentView a view to dismiss
@param {Function} callback the callback called once operation is terminated
*/
dismissCurrentView: function(currentView, callback) {
callback();
},
/**
This method is responsible for removing a view from the containerView
You may want to override it in case you implementing views sharing for example
@param {Ember.View} currentView a view to present
@param {Function} callback the callback called once view is removed
*/
removeCurrentView: function(currentView, callback) {
var childViews = get(this, 'childViews');
currentView.one('didDisappear', function() {
currentView.destroy();
});
childViews.removeObject(currentView);
callback();
},
_currentViewWillChange: Ember.beforeObserver(function() {
var childViews = get(this, 'childViews'),
currentView = get(this, 'currentView');
var currentView = get(this, 'currentView'),
containerView = this;
if (currentView) {
childViews.removeObject(currentView);
currentView.destroy();
set(currentView, 'isBeingDismissed', true);
currentView.trigger('willDisappear', currentView);
this.dismissCurrentView(currentView, function() {
containerView.removeCurrentView(currentView, function() {
set(currentView, 'isBeingDismissed', false);
currentView.trigger('didDisappear', currentView);
});
});
}
}, 'currentView'),
_currentViewDidChange: Ember.observer(function() {
var childViews = get(this, 'childViews'),
currentView = get(this, 'currentView');
var currentView = get(this, 'currentView'),
containerView = this;
if (currentView) {
childViews.pushObject(currentView);
set(currentView, 'isBeingPresented', true);

This comment has been minimized.

@krisselden

krisselden Aug 21, 2012

Member

why is this needed in addition to the willAppear/didAppear events?

@krisselden

krisselden Aug 21, 2012

Member

why is this needed in addition to the willAppear/didAppear events?

This comment has been minimized.

@tchak

tchak Aug 22, 2012

Member

I thought some one could want do in a template

{{#if view.isBeingPresented}}
  I am entering the screen!
{{/if}}
@tchak

tchak Aug 22, 2012

Member

I thought some one could want do in a template

{{#if view.isBeingPresented}}
  I am entering the screen!
{{/if}}
currentView.trigger('willAppear', currentView);
this.appendCurrentView(currentView, function() {
containerView.presentCurrentView(currentView, function() {
set(currentView, 'isBeingPresented', false);
currentView.trigger('didAppear', currentView);
});
});
}
}, 'currentView'),
@@ -494,3 +494,53 @@ test("should invalidate `element` on itself and childViews when being rendered b
ok(!!container.get('element'), "Parent's element should have been recomputed after being rendered");
ok(!!view.get('element'), "Child's element should have been recomputed after being rendered");
});
test("should execut all the hooks when removing or adding a currentView", function() {
expect(9);
var viewsCount = 0;
var container = Ember.ContainerView.create({
presentCurrentView: function(currentView, callback) {
if (viewsCount === 1) {
equal(currentView, child1, 'will present child1');
equal(child1.get('isBeingPresented'), true);
} else {
equal(currentView, child2, 'will present child2');
equal(child2.get('isBeingPresented'), true);
}
callback();
},
appendCurrentView: function(currentView, callback) {
viewsCount++;
if (viewsCount === 1) {
equal(currentView, child1, 'will append child1');
} else {
equal(currentView, child2, 'will append child2');
}
this._super(currentView, callback);
},
dismissCurrentView: function(currentView, callback) {
equal(child1.get('isBeingDismissed'), true);
equal(currentView, child1, 'will dismiss child1');
callback();
},
removeCurrentView: function(currentView, callback) {
equal(currentView, child1, 'will remove child1');
this._super(currentView, callback);
}
});
var child1 = Ember.View.create();
var child2 = Ember.View.create();
Ember.run(function() {
container.appendTo('#qunit-fixture');
});
Ember.run(function() {
set(container, 'currentView', child1);
});
Ember.run(function() {
set(container, 'currentView', child2);
});
});
ProTip! Use n and p to navigate between commits in a pull request.