diff options
Diffstat (limited to 'src/ngRoute/directive/ngView.js')
| -rw-r--r-- | src/ngRoute/directive/ngView.js | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/ngRoute/directive/ngView.js b/src/ngRoute/directive/ngView.js new file mode 100644 index 00000000..935ba05d --- /dev/null +++ b/src/ngRoute/directive/ngView.js @@ -0,0 +1,226 @@ +'use strict'; + +ngRouteModule.directive('ngView', ngViewFactory); + +/** + * @ngdoc directive + * @name ngRoute.directive:ngView + * @restrict ECA + * + * @description + * # Overview + * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by + * including the rendered template of the current route into the main layout (`index.html`) file. + * Every time the current route changes, the included view changes with it according to the + * configuration of the `$route` service. + * + * Additionally, you can also provide animations via the ngAnimate attribute to animate the **enter** + * and **leave** effects. + * + * @animations + * enter - happens just after the ngView contents are changed (when the new view DOM element is inserted into the DOM) + * leave - happens just after the current ngView contents change and just before the former contents are removed from the DOM + * + * @scope + * @example + <example module="ngViewExample" deps="angular-route.js" animations="true"> + <file name="index.html"> + <div ng-controller="MainCntl as main"> + Choose: + <a href="Book/Moby">Moby</a> | + <a href="Book/Moby/ch/1">Moby: Ch1</a> | + <a href="Book/Gatsby">Gatsby</a> | + <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> | + <a href="Book/Scarlet">Scarlet Letter</a><br/> + + <div + ng-view + class="example-animate-container" + ng-animate="{enter: 'example-enter', leave: 'example-leave'}"></div> + <hr /> + + <pre>$location.path() = {{main.$location.path()}}</pre> + <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre> + <pre>$route.current.params = {{main.$route.current.params}}</pre> + <pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre> + <pre>$routeParams = {{main.$routeParams}}</pre> + </div> + </file> + + <file name="book.html"> + <div> + controller: {{book.name}}<br /> + Book Id: {{book.params.bookId}}<br /> + </div> + </file> + + <file name="chapter.html"> + <div> + controller: {{chapter.name}}<br /> + Book Id: {{chapter.params.bookId}}<br /> + Chapter Id: {{chapter.params.chapterId}} + </div> + </file> + + <file name="animations.css"> + .example-leave, .example-enter { + -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + -moz-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + -ms-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + -o-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s; + } + + .example-animate-container { + position:relative; + height:100px; + } + + .example-animate-container > * { + display:block; + width:100%; + border-left:1px solid black; + + position:absolute; + top:0; + left:0; + right:0; + bottom:0; + padding:10px; + } + + .example-enter { + left:100%; + } + .example-enter.example-enter-active { + left:0; + } + + .example-leave { } + .example-leave.example-leave-active { + left:-100%; + } + </file> + + <file name="script.js"> + angular.module('ngViewExample', ['ngRoute'], function($routeProvider, $locationProvider) { + $routeProvider.when('/Book/:bookId', { + templateUrl: 'book.html', + controller: BookCntl, + controllerAs: 'book' + }); + $routeProvider.when('/Book/:bookId/ch/:chapterId', { + templateUrl: 'chapter.html', + controller: ChapterCntl, + controllerAs: 'chapter' + }); + + // configure html5 to get links working on jsfiddle + $locationProvider.html5Mode(true); + }); + + function MainCntl($route, $routeParams, $location) { + this.$route = $route; + this.$location = $location; + this.$routeParams = $routeParams; + } + + function BookCntl($routeParams) { + this.name = "BookCntl"; + this.params = $routeParams; + } + + function ChapterCntl($routeParams) { + this.name = "ChapterCntl"; + this.params = $routeParams; + } + </file> + + <file name="scenario.js"> + it('should load and compile correct template', function() { + element('a:contains("Moby: Ch1")').click(); + var content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: ChapterCntl/); + expect(content).toMatch(/Book Id\: Moby/); + expect(content).toMatch(/Chapter Id\: 1/); + + element('a:contains("Scarlet")').click(); + content = element('.doc-example-live [ng-view]').text(); + expect(content).toMatch(/controller\: BookCntl/); + expect(content).toMatch(/Book Id\: Scarlet/); + }); + </file> + </example> + */ + + +/** + * @ngdoc event + * @name ngRoute.directive:ngView#$viewContentLoaded + * @eventOf ngRoute.directive:ngView + * @eventType emit on the current ngView scope + * @description + * Emitted every time the ngView content is reloaded. + */ +ngViewFactory.$inject = ['$route', '$anchorScroll', '$compile', '$controller', '$animator']; +function ngViewFactory( $route, $anchorScroll, $compile, $controller, $animator) { + return { + restrict: 'ECA', + terminal: true, + link: function(scope, element, attr) { + var lastScope, + onloadExp = attr.onload || '', + animate = $animator(scope, attr); + + scope.$on('$routeChangeSuccess', update); + update(); + + + function destroyLastScope() { + if (lastScope) { + lastScope.$destroy(); + lastScope = null; + } + } + + function clearContent() { + animate.leave(element.contents(), element); + destroyLastScope(); + } + + function update() { + var locals = $route.current && $route.current.locals, + template = locals && locals.$template; + + if (template) { + clearContent(); + var enterElements = jqLite('<div></div>').html(template).contents(); + animate.enter(enterElements, element); + + var link = $compile(enterElements), + current = $route.current, + controller; + + lastScope = current.scope = scope.$new(); + if (current.controller) { + locals.$scope = lastScope; + controller = $controller(current.controller, locals); + if (current.controllerAs) { + lastScope[current.controllerAs] = controller; + } + element.children().data('$ngControllerController', controller); + } + + link(lastScope); + lastScope.$emit('$viewContentLoaded'); + lastScope.$eval(onloadExp); + + // $anchorScroll might listen on event... + $anchorScroll(); + } else { + clearContent(); + } + } + } + }; +} |
