mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-04-15 12:21:05 +00:00
Currently, the documentation does a bad job of explaining the distinction between the services that it provides,
and the module itself. Furthermore, the instructions for using optional modules are inconsistent or missing.
This commit addresses the problem by ading a new `{@installModule foo}` annotation to the docs generator that
inlines the appropriate instructions based on the name of the module.
242 lines
7.4 KiB
JavaScript
242 lines
7.4 KiB
JavaScript
'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.
|
|
*
|
|
* Requires the {@link ngRoute `ngRoute`} module to be installed.
|
|
*
|
|
* @animations
|
|
* enter - animation is used to bring new content into the browser.
|
|
* leave - animation is used to animate existing content away.
|
|
*
|
|
* The enter and leave animation occur concurrently.
|
|
*
|
|
* @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 class="example-animate-container">
|
|
<div ng-view class="view-example"></div>
|
|
</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-animate-container {
|
|
position:relative;
|
|
background:white;
|
|
border:1px solid black;
|
|
height:40px;
|
|
overflow:hidden;
|
|
}
|
|
|
|
.example-animate-container > div {
|
|
padding:10px;
|
|
}
|
|
|
|
.view-example.ng-enter, .view-example.ng-leave {
|
|
-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;
|
|
-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;
|
|
|
|
display:block;
|
|
width:100%;
|
|
border-left:1px solid black;
|
|
|
|
position:absolute;
|
|
top:0;
|
|
left:0;
|
|
right:0;
|
|
bottom:0;
|
|
padding:10px;
|
|
}
|
|
|
|
.example-animate-container {
|
|
position:relative;
|
|
height:100px;
|
|
}
|
|
|
|
.view-example.ng-enter {
|
|
left:100%;
|
|
}
|
|
.view-example.ng-enter.ng-enter-active {
|
|
left:0;
|
|
}
|
|
|
|
.view-example.ng-leave { }
|
|
.view-example.ng-leave.ng-leave-active {
|
|
left:-100%;
|
|
}
|
|
</file>
|
|
|
|
<file name="script.js">
|
|
angular.module('ngViewExample', ['ngRoute', 'ngAnimate'], 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', '$animate'];
|
|
function ngViewFactory( $route, $anchorScroll, $compile, $controller, $animate) {
|
|
return {
|
|
restrict: 'ECA',
|
|
terminal: true,
|
|
transclude: 'element',
|
|
compile: function(element, attr, linker) {
|
|
return function(scope, $element, attr) {
|
|
var currentScope,
|
|
currentElement,
|
|
onloadExp = attr.onload || '';
|
|
|
|
scope.$on('$routeChangeSuccess', update);
|
|
update();
|
|
|
|
function cleanupLastView() {
|
|
if (currentScope) {
|
|
currentScope.$destroy();
|
|
currentScope = null;
|
|
}
|
|
if(currentElement) {
|
|
$animate.leave(currentElement);
|
|
currentElement = null;
|
|
}
|
|
}
|
|
|
|
function update() {
|
|
var locals = $route.current && $route.current.locals,
|
|
template = locals && locals.$template;
|
|
|
|
if (template) {
|
|
var newScope = scope.$new();
|
|
linker(newScope, function(clone) {
|
|
cleanupLastView();
|
|
|
|
clone.html(template);
|
|
$animate.enter(clone, null, $element);
|
|
|
|
var link = $compile(clone.contents()),
|
|
current = $route.current;
|
|
|
|
currentScope = current.scope = newScope;
|
|
currentElement = clone;
|
|
|
|
if (current.controller) {
|
|
locals.$scope = currentScope;
|
|
var controller = $controller(current.controller, locals);
|
|
if (current.controllerAs) {
|
|
currentScope[current.controllerAs] = controller;
|
|
}
|
|
clone.data('$ngControllerController', controller);
|
|
clone.contents().data('$ngControllerController', controller);
|
|
}
|
|
|
|
link(currentScope);
|
|
currentScope.$emit('$viewContentLoaded');
|
|
currentScope.$eval(onloadExp);
|
|
|
|
// $anchorScroll might listen on event...
|
|
$anchorScroll();
|
|
});
|
|
} else {
|
|
cleanupLastView();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|