1+ 'use strict' ;
2+
3+ /**
4+ * The directive app:view is more powerful replacement of built-in ng:view. It allows views to be nested, where each
5+ * following view in the chain corresponds to the next route segment (see $routeSegment service).
6+ *
7+ * Sample:
8+ * <div>
9+ * <h4>Section</h4>
10+ * <div app:view>Nothing selected</div>
11+ * </div>
12+ *
13+ * Initial contents of an element with app:view will display if corresponding route segment doesn't exist.
14+ *
15+ * View resolving are depends on route segment params:
16+ * - `template` define contents of the view
17+ * - `controller` is attached to view contents when compiled and linked
18+ */
19+
20+ ( function ( angular ) {
21+
22+ angular . module ( 'view-segment' , [ 'route-segment' ] ) . directive ( 'appViewSegment' ,
23+ [ '$route' , '$compile' , '$controller' , '$routeParams' , '$routeSegment' , '$q' , '$injector' ,
24+ function ( $route , $compile , $controller , $routeParams , $routeSegment , $q , $injector ) {
25+
26+ return {
27+ restrict : 'ECA' ,
28+ priority : 500 ,
29+ compile : function ( tElement , tAttrs ) {
30+
31+ var defaultContent = tElement . html ( ) , isDefault = true ,
32+ anchor = angular . element ( document . createComment ( ' view-segment ' ) ) ;
33+
34+ tElement . prepend ( anchor ) ;
35+
36+ return function ( $scope ) {
37+
38+ var currentScope , currentElement , onloadExp = tAttrs . onload || '' , animate ,
39+ viewSegmentIndex = parseInt ( tAttrs . appViewSegment ) ;
40+
41+ try {
42+ // angular 1.1.x
43+ var $animator = $injector . get ( '$animator' )
44+ animate = $animator ( $scope , tAttrs ) ;
45+ }
46+ catch ( e ) { }
47+ try {
48+ // angular 1.2.x
49+ animate = $injector . get ( '$animate' ) ;
50+ }
51+ catch ( e ) { }
52+
53+ // Watching for the specified route segment and updating contents
54+ $scope . $on ( 'routeSegmentChange' , function ( event , args ) {
55+ if ( args . index == viewSegmentIndex )
56+ update ( args . segment ) ;
57+ } ) ;
58+
59+ function clearContent ( ) {
60+
61+ if ( currentElement ) {
62+ animate . leave ( currentElement ) ;
63+ currentElement = null ;
64+ }
65+
66+ if ( currentScope ) {
67+ currentScope . $destroy ( ) ;
68+ currentScope = null ;
69+ }
70+ }
71+
72+
73+ function update ( segment ) {
74+
75+ if ( ! segment ) {
76+ clearContent ( ) ;
77+ currentElement = tElement . clone ( ) ;
78+ currentElement . html ( defaultContent ) ;
79+ animate . enter ( currentElement , null , anchor ) ;
80+ $compile ( currentElement , false , 499 ) ( $scope ) ;
81+ return ;
82+ }
83+
84+ if ( isDefault ) {
85+ isDefault = false ;
86+ tElement . replaceWith ( anchor ) ;
87+ }
88+
89+ var locals = angular . extend ( { } , segment . locals ) ,
90+ template = locals && locals . $template ;
91+
92+ if ( template ) {
93+
94+ clearContent ( ) ;
95+
96+ currentElement = tElement . clone ( ) ;
97+ currentElement . html ( template ) ;
98+ animate . enter ( currentElement , null , anchor ) ;
99+
100+ var link = $compile ( currentElement , false , 499 ) , controller ;
101+
102+ currentScope = $scope . $new ( ) ;
103+ if ( segment . params . controller ) {
104+ locals . $scope = currentScope ;
105+ controller = $controller ( segment . params . controller , locals ) ;
106+ currentElement . data ( '$ngControllerController' , controller ) ;
107+ currentElement . children ( ) . data ( '$ngControllerController' , controller ) ;
108+ }
109+
110+ link ( currentScope ) ;
111+ currentScope . $emit ( '$viewContentLoaded' ) ;
112+ currentScope . $eval ( onloadExp ) ;
113+ } else {
114+ clearContent ( ) ;
115+ }
116+ }
117+ }
118+ }
119+ }
120+ } ] ) ;
121+
122+ } ) ( angular ) ;
0 commit comments