aboutsummaryrefslogtreecommitdiffstats
path: root/src/ngRoute/directive/ngView.js
diff options
context:
space:
mode:
authorIgor Minar2013-06-05 15:30:31 -0700
committerIgor Minar2013-06-06 17:07:12 -0700
commit5599b55b04788c2e327d7551a4a699d75516dd21 (patch)
treedc080ce9639f44056eb6c476fb030923249ce265 /src/ngRoute/directive/ngView.js
parent7a5cfb593f27c28cee545974736632bf8da62fe8 (diff)
downloadangular.js-5599b55b04788c2e327d7551a4a699d75516dd21.tar.bz2
refactor($route): pull $route and friends into angular-route.js
$route, $routeParams and ngView have been pulled from core angular.js to angular-route.js/ngRoute module. This is was done to in order keep the core focused on most commonly used functionality and allow community routers to be freely used instead of $route service. There is no need to panic, angular-route will keep on being supported by the angular team. Note: I'm intentionally not fixing tutorial links. Tutorial will need bigger changes and those should be done when we update tutorial to 1.2. BREAKING CHANGE: applications that use $route will now need to load angular-route.js file and define dependency on ngRoute module. Before: ``` ... <script src="angular.js"></script> ... var myApp = angular.module('myApp', ['someOtherModule']); ... ``` After: ``` ... <script src="angular.js"></script> <script src="angular-route.js"></script> ... var myApp = angular.module('myApp', ['ngRoute', 'someOtherModule']); ... ``` Closes #2804
Diffstat (limited to 'src/ngRoute/directive/ngView.js')
-rw-r--r--src/ngRoute/directive/ngView.js226
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();
+ }
+ }
+ }
+ };
+}