Skip to content

Commit

Permalink
fix: defer unregistering sequenced items until their elements, not th…
Browse files Browse the repository at this point in the history
…eir scopes, are destroyed
  • Loading branch information
stristr committed Jun 23, 2014
1 parent a3764d2 commit 8517838
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 37 deletions.
12 changes: 6 additions & 6 deletions src/scripts/directives/fa-flipper.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
*@example
* A Famous Flipper has a `.flip()` method that toggles a rotation between front and back sides.
* In the example below, when an `fa-surface` is clicked, it calls the function `flipIt`.
*
* This function attempts a DOM lookup for an isolate of an `fa-flipper` element, and calls the `.flip()` function of `fa-flipper`.
*
*
* This function attempts a DOM lookup for an isolate of an `fa-flipper` element, and calls the `.flip()` function of `fa-flipper`.
*
*```html
* <fa-flipper>
* <fa-surface fa-background-color="'yellow'" fa-click="flipIt()"></fa-surface>
Expand Down Expand Up @@ -50,18 +50,18 @@ angular.module('famous.angular')

//TODO: $watch and update, or $parse and attr.$observe
var options = scope.$eval(attrs.faOptions) || {};

isolate.renderNode = new Flipper(options);
isolate.children = [];

isolate.flip = function (overrideOptions) {
isolate.renderNode.flip(overrideOptions || scope.$eval(attrs.faOptions));
};

scope.$on('$destroy', function() {
element.one('$destroy', function() {
scope.$emit('unregisterChild', {id: scope.$id});
});

scope.$on('registerChild', function (evt, data) {
if (evt.targetScope.$id != scope.$id) {
var _childCount = isolate.children.length;
Expand Down
5 changes: 1 addition & 4 deletions src/scripts/directives/fa-modifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -363,14 +363,11 @@ angular.module('famous.angular')

isolate.renderNode = new RenderNode().add(isolate.modifier)

scope.$on('$destroy', function() {
scope.$emit('unregisterChild', {id: scope.$id});
});

// When the actual element is destroyed by Angular,
// "hide" the Modifier by setting its opacity to 0.
element.one('$destroy', function() {
isolate.modifier.setOpacity(0);
scope.$emit('unregisterChild', {id: scope.$id});
});


Expand Down
32 changes: 16 additions & 16 deletions src/scripts/directives/fa-render-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,38 @@
* </fa-render-node>
* ```
* @example
* `Fa-render-node` can wrap a custom-made widget or any renderable component from Famous and allow it to be inserted in the Render Tree.
*
* `Fa-render-node` can wrap a custom-made widget or any renderable component from Famous and allow it to be inserted in the Render Tree.
*
* All Famous widgets, such as a Scroll View, a Sequential Layout, or a Header-footer-layout, are extended Famous Views.
* `Fa-render-node` allows a developer to create & extend their own Famous View, and use it within their own Famous-Angular app.
*
* `Fa-render-node` allows a developer to create & extend their own Famous View, and use it within their own Famous-Angular app.
*
* In the example below, a Famous View is instantiated on the scope; a Modifier is added to it, and then a Surface is added below.
* This approach of creating a View and adding renderables to it with the `.add()` method is more in line with a "vanilla Famous" approach than a declarative approach with Famous-Angular.
*
* This approach of creating a View and adding renderables to it with the `.add()` method is more in line with a "vanilla Famous" approach than a declarative approach with Famous-Angular.
*
* In the html view, an `fa-render-node` is declared, with an `fa-node` attribute bound to the newly-created View on the scope, resulting in our custom View appearing on the page.
*
*
* ```javascript
* var View = $famous['famous/core/View'];
* var Modifier = $famous['famous/core/Modifier'];
* var Surface = $famous['famous/core/Surface'];
* var Transform = $famous['famous/core/Transform'];
*
*
* $scope.masterView = new View();
*
*
* var _surf = new Surface({properties: {backgroundColor: 'red'}});
* _surf.setContent("I'm a surface");
*
*
* var _mod = new Modifier();
*
*
* var _width = 320;
* var _height = 568;
* _mod.transformFrom(function(){
* return Transform.translate(Math.random() * _width, 0, 1);
* });
*
*
* $scope.masterView.add(_mod).add(_surf);
* ```
*
*
* ```html
* <fa-render-node fa-node="masterView" id="render"></fa-render-node>
* ```
Expand All @@ -62,7 +62,7 @@ angular.module('famous.angular')
return {
pre: function(scope, element, attrs){
var isolate = $famousDecorator.ensureIsolate(scope);

var Engine = $famous['famous/core/Engine'];

var getOrValue = function(x) {
Expand All @@ -79,7 +79,7 @@ angular.module('famous.angular')

isolate.renderNode = scope.$eval(attrs.faNode);

scope.$on('$destroy', function() {
element.one('$destroy', function() {
scope.$emit('unregisterChild', {id: scope.$id});
});

Expand All @@ -94,7 +94,7 @@ angular.module('famous.angular')
},
post: function(scope, element, attrs){
var isolate = $famousDecorator.ensureIsolate(scope);

transclude(scope, function(clone) {
element.find('div').append(clone);
});
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/directives/fa-surface.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ angular.module('famous.angular')
isolate.renderNode.setClasses(attrs['class'].split(' '));
}

scope.$on('$destroy', function() {
element.one('$destroy', function() {
//TODO: hook into RenderController and hide this render node
// This whole function (scope.$on...) can probably
// be handled by the $famousDecorator
Expand Down
20 changes: 10 additions & 10 deletions src/scripts/directives/fa-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
* </fa-view>
* ```
* @example
* A Famous View is used for encapsulating many Modifiers and Surfaces together. Internally, it is a Render Node that has its own input EventHandler (`_eventInput`) and output EventHandler (`_eventOutput`).
* A Famous View is used for encapsulating many Modifiers and Surfaces together. Internally, it is a Render Node that has its own input EventHandler (`_eventInput`) and output EventHandler (`_eventOutput`).
* It does not map to DOM elements, but rather, it is an empty Render Node that can be extended by a developer.
* A View's input eventHandler is the aggregation point of all events coming into the View, and from there, the View can listen for specific events and handle them.
*
*
* A more concrete example is a Scroll View: it is a Famous View that has been extended with certain sets of behavior to handle events such as a mouse scroll.
* In the example below, when an `fa-surface` within an `fa-scroll-view` propagates an event (such as mouse scroll), these events are piped to the Scroll View (through `fa-pipe-to`). These events go through the Scroll View's `_eventInput` (using `fa-pipe-from`). From there, the Scroll View has pre-defined event handlers to handle these events.
* In the example below, when an `fa-surface` within an `fa-scroll-view` propagates an event (such as mouse scroll), these events are piped to the Scroll View (through `fa-pipe-to`). These events go through the Scroll View's `_eventInput` (using `fa-pipe-from`). From there, the Scroll View has pre-defined event handlers to handle these events.
*
* Famous Views are a way to encapsulate large event systems with renderables (Surfaces & Modifiers).
*
Expand All @@ -30,18 +30,18 @@
* <fa-surface fa-pipe-to="myEventHandler"></fa-surface>
* </fa-modifier>
* </fa-view>
* </fa-scroll-view>
* </fa-scroll-view>
*```
* ```javascript
* var EventHandler = $famous['famous/core/EventHandler'];
* $scope.myEventHandler = new EventHandler();
* ```
*
*
* ### Event propagation within & between Views
* In the Famous event model, an `fa-view` nested within another `fa-view` does not automatically propagate its events to its parent.
* Not even an `fa-surface` nested inside an `fa-view` propagates its events to the `fa-view`. All events to an `fa-view` must be piped explicitly.
* Not even an `fa-surface` nested inside an `fa-view` propagates its events to the `fa-view`. All events to an `fa-view` must be piped explicitly.
*
* For a more thorough discussion on Famous-Angular events, go to fa-pipe-from/fa-pipe-to in the docs.
* For a more thorough discussion on Famous-Angular events, go to fa-pipe-from/fa-pipe-to in the docs.
*/

angular.module('famous.angular')
Expand All @@ -53,7 +53,7 @@ angular.module('famous.angular')
restrict: 'EA',
compile: function(tElement, tAttrs, transclude){
var View = $famous['famous/core/View'];

return {
pre: function(scope, element, attrs){
var isolate = $famousDecorator.ensureIsolate(scope);
Expand All @@ -68,7 +68,7 @@ angular.module('famous.angular')
size: scope.$eval(attrs.faSize) || [undefined, undefined]
});

scope.$on('$destroy', function() {
element.one('$destroy', function() {
scope.$emit('unregisterChild', {id: scope.$id});
});

Expand All @@ -83,7 +83,7 @@ angular.module('famous.angular')
},
post: function(scope, element, attrs){
var isolate = $famousDecorator.ensureIsolate(scope);

transclude(scope, function(clone) {
element.find('div').append(clone);
});
Expand Down

0 comments on commit 8517838

Please sign in to comment.