<!doctype html>
<html ng-app="Demo">
<head>
	<meta charset="utf-8" />

	<title>
		How The $destroy Event Affects The Scope Tree In AngularJS
	</title>

	<link rel="stylesheet" type="text/css" href="./demo.css"><link>
</head>
<body ng-controller="AppController">

	<h1>
		How The $destroy Event Affects The Scope Tree In AngularJS
	</h1>

	<p>
		<a ng-click="toggleContainer()">Toggle Container(s)</a>
	</p>

	<!-- NOTE: We are using ngIf here to ensure multiple scope are created. -->
	<div ng-if="isShowingContainer" bn-logger>

		<div ng-if="true" bn-logger>

			<div ng-if="true" bn-logger>

				Inner inner inner thing.

			</div>

		</div>

	</div>


	<!-- Load scripts. -->
	<script type="text/javascript" src="../../vendor/angularjs/angular-1.4.2.min.js"></script>
	<script type="text/javascript">

		// Create an application module for our demo.
		var app = angular.module( "Demo", [] );


		// --------------------------------------------------------------------------- //
		// --------------------------------------------------------------------------- //


		// I control the root of the application.
		angular.module( "Demo" ).controller(
			"AppController",
			function AppController( $scope ) {

				// I determine if we are showing the container.
				$scope.isShowingContainer = true;


				// ---
				// PUBLIC METHODS.
				// ---


				// I toggle the existence of the container.
				$scope.toggleContainer = function() {

					$scope.isShowingContainer = ! $scope.isShowingContainer;

				};

			}
		);


		// --------------------------------------------------------------------------- //
		// --------------------------------------------------------------------------- //


		// I log the scope-parent relationship in and around the $destroy event.
		angular.module( "Demo" ).directive(
			"bnLogger",
			function bnLogger( $timeout ) {

				// Return the directive configuration object.
				return({
					link: link,
					restrict: "A"
				});


				// I bind the JavaScript events to the view-model.
				function link( scope, element, attributes ) {

					// When the $destroy event is triggered, we want to see how it affects
					// the relationship between the current scope and its parent scope.
					scope.$on(
						"$destroy",
						function handleDestroy() {

							logIDs( "Before Timeout" );

							// Since the "$destroy" event is triggered before the the
							// scope tree is altered, we need to wait a tick and then
							// check the parent structure again.
							$timeout( logIDs, 0, false );

						}

					);


					// I log the IDs of the current scope and parent scope.
					function logIDs( prefix ) {

						// What we'll see here is that the $parent is NULL for the root
						// of the scope sub-tree that was destroyed; but, for all the
						// non-root nodes, the $parent scope will be in tact.
						// --
						// CAUTION: The $$destroyed property is a proprietary AngularJS
						// property; it is not meant to be referenced outside of the
						// framework. I am just logging it here for clarity.
						console.log(
							"%s: Scope [%s] with parent scope [%s] .. $$destroyed [%s].",
							( prefix || "After Timeout" ),
							scope.$id,
							( scope.$parent && scope.$parent.$id ),
							scope.$$destroyed
						);

					}

				}

			}
		);

	</script>

</body>
</html>