docs: Refresh content on routable animations for router guide (#20023)
PR Close #20023
This commit is contained in:

committed by
Kara Erickson

parent
c8817f39a9
commit
c9fece997c
@ -13,33 +13,34 @@ describe('Router', () => {
|
||||
|
||||
function getPageStruct() {
|
||||
const hrefEles = element.all(by.css('app-root > nav a'));
|
||||
const crisisDetail = element.all(by.css('app-root > ng-component > ng-component > ng-component > div')).first();
|
||||
const heroDetail = element(by.css('app-root > ng-component > div'));
|
||||
const crisisDetail = element.all(by.css('app-root > div > ng-component > ng-component > ng-component > div')).first();
|
||||
const heroDetail = element(by.css('app-root > div > ng-component'));
|
||||
|
||||
return {
|
||||
hrefs: hrefEles,
|
||||
activeHref: element(by.css('app-root > nav a.active')),
|
||||
|
||||
crisisHref: hrefEles.get(0),
|
||||
crisisList: element.all(by.css('app-root > ng-component > ng-component li')),
|
||||
crisisList: element.all(by.css('app-root > div > ng-component > ng-component li')),
|
||||
crisisDetail: crisisDetail,
|
||||
crisisDetailTitle: crisisDetail.element(by.xpath('*[1]')),
|
||||
|
||||
heroesHref: hrefEles.get(1),
|
||||
heroesList: element.all(by.css('app-root > ng-component li')),
|
||||
heroesList: element.all(by.css('app-root > div > ng-component li')),
|
||||
heroDetail: heroDetail,
|
||||
heroDetailTitle: heroDetail.element(by.xpath('*[1]')),
|
||||
heroDetailTitle: heroDetail.element(by.xpath('*[2]')),
|
||||
|
||||
adminHref: hrefEles.get(2),
|
||||
adminPreloadList: element.all(by.css('app-root > ng-component > ng-component > ul > li')),
|
||||
adminPreloadList: element.all(by.css('app-root > div > ng-component > ng-component > ul > li')),
|
||||
|
||||
loginHref: hrefEles.get(3),
|
||||
loginButton: element.all(by.css('app-root > ng-component > p > button')),
|
||||
loginButton: element.all(by.css('app-root > div > ng-component > p > button')),
|
||||
|
||||
contactHref: hrefEles.get(4),
|
||||
contactCancelButton: element.all(by.buttonText('Cancel')),
|
||||
|
||||
outletComponents: element.all(by.css('app-root > ng-component'))
|
||||
primaryOutlet: element.all(by.css('app-root > div > ng-component')),
|
||||
secondaryOutlet: element.all(by.css('app-root > ng-component'))
|
||||
};
|
||||
}
|
||||
|
||||
@ -98,6 +99,7 @@ describe('Router', () => {
|
||||
it('saves changed hero details', async () => {
|
||||
const page = getPageStruct();
|
||||
await page.heroesHref.click();
|
||||
await browser.sleep(600);
|
||||
const heroEle = page.heroesList.get(4);
|
||||
let text = await heroEle.getText();
|
||||
expect(text.length).toBeGreaterThan(0, 'hero item text length');
|
||||
@ -105,6 +107,7 @@ describe('Router', () => {
|
||||
const heroText = text.substr(text.indexOf(' ')).trim();
|
||||
|
||||
await heroEle.click();
|
||||
await browser.sleep(600);
|
||||
expect(page.heroesList.count()).toBe(0, 'hero list count');
|
||||
expect(page.heroDetail.isPresent()).toBe(true, 'hero detail');
|
||||
expect(page.heroDetailTitle.getText()).toContain(heroText);
|
||||
@ -114,6 +117,7 @@ describe('Router', () => {
|
||||
|
||||
let buttonEle = page.heroDetail.element(by.css('button'));
|
||||
await buttonEle.click();
|
||||
await browser.sleep(600);
|
||||
expect(heroEle.getText()).toContain(heroText + '-foo');
|
||||
});
|
||||
|
||||
@ -130,7 +134,8 @@ describe('Router', () => {
|
||||
const page = getPageStruct();
|
||||
await page.heroesHref.click();
|
||||
await page.contactHref.click();
|
||||
expect(page.outletComponents.count()).toBe(2, 'route count');
|
||||
expect(page.primaryOutlet.count()).toBe(1, 'primary outlet');
|
||||
expect(page.secondaryOutlet.count()).toBe(1, 'secondary outlet');
|
||||
});
|
||||
|
||||
async function crisisCenterEdit(index: number, save: boolean) {
|
||||
|
@ -1,26 +1,35 @@
|
||||
// #docregion
|
||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||
import {
|
||||
trigger, animateChild, group,
|
||||
transition, animate, style, query
|
||||
} from '@angular/animations';
|
||||
|
||||
// Component transition animations
|
||||
export const slideInDownAnimation =
|
||||
|
||||
// Routable animations
|
||||
export const slideInAnimation =
|
||||
trigger('routeAnimation', [
|
||||
state('*',
|
||||
style({
|
||||
opacity: 1,
|
||||
transform: 'translateX(0)'
|
||||
})
|
||||
),
|
||||
transition(':enter', [
|
||||
style({
|
||||
opacity: 0,
|
||||
transform: 'translateX(-100%)'
|
||||
}),
|
||||
animate('0.2s ease-in')
|
||||
]),
|
||||
transition(':leave', [
|
||||
animate('0.5s ease-out', style({
|
||||
opacity: 0,
|
||||
transform: 'translateY(100%)'
|
||||
}))
|
||||
transition('heroes <=> hero', [
|
||||
style({ position: 'relative' }),
|
||||
query(':enter, :leave', [
|
||||
style({
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%'
|
||||
})
|
||||
]),
|
||||
query(':enter', [
|
||||
style({ left: '-100%'})
|
||||
]),
|
||||
query(':leave', animateChild()),
|
||||
group([
|
||||
query(':leave', [
|
||||
animate('300ms ease-out', style({ left: '100%'}))
|
||||
]),
|
||||
query(':enter', [
|
||||
animate('300ms ease-out', style({ left: '0%'}))
|
||||
])
|
||||
]),
|
||||
query(':enter', animateChild()),
|
||||
])
|
||||
]);
|
||||
|
@ -1,16 +1,31 @@
|
||||
/* Second Heroes version */
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
// #docregion animation-imports
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { slideInAnimation } from './animations';
|
||||
// #enddocregion animation-imports
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
// #docregion template
|
||||
template: `
|
||||
<h1>Angular Router</h1>
|
||||
<nav>
|
||||
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
|
||||
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
`
|
||||
<div [@routeAnimation]="getAnimationData(routerOutlet)">
|
||||
<router-outlet #routerOutlet="outlet"></router-outlet>
|
||||
</div>
|
||||
`,
|
||||
animations: [ slideInAnimation ]
|
||||
// #enddocregion template
|
||||
})
|
||||
export class AppComponent { }
|
||||
// #docregion function-binding
|
||||
export class AppComponent {
|
||||
getAnimationData(outlet: RouterOutlet) {
|
||||
return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation'];
|
||||
}
|
||||
}
|
||||
// #enddocregion function-binding
|
||||
|
@ -14,7 +14,9 @@ import { Component } from '@angular/core';
|
||||
// #enddocregion contact-link
|
||||
</nav>
|
||||
// #docregion outlets
|
||||
<router-outlet></router-outlet>
|
||||
<div [@routeAnimation]="getAnimationData(routerOutlet)">
|
||||
<router-outlet #routerOutlet="outlet"></router-outlet>
|
||||
</div>
|
||||
<router-outlet name="popup"></router-outlet>
|
||||
// #enddocregion outlets
|
||||
`
|
||||
|
@ -12,7 +12,9 @@ import { Component } from '@angular/core';
|
||||
<a routerLink="/admin" routerLinkActive="active">Admin</a>
|
||||
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
<div [@routeAnimation]="getAnimationData(routerOutlet)">
|
||||
<router-outlet #routerOutlet="outlet"></router-outlet>
|
||||
</div>
|
||||
<router-outlet name="popup"></router-outlet>
|
||||
`
|
||||
// #enddocregion template
|
||||
|
@ -14,7 +14,9 @@ import { Component } from '@angular/core';
|
||||
<a routerLink="/login" routerLinkActive="active">Login</a>
|
||||
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
<div [@routeAnimation]="getAnimationData(routerOutlet)">
|
||||
<router-outlet #routerOutlet="outlet"></router-outlet>
|
||||
</div>
|
||||
<router-outlet name="popup"></router-outlet>
|
||||
`
|
||||
// #enddocregion template
|
||||
|
@ -1,6 +1,8 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { slideInAnimation } from './animations';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@ -14,10 +16,16 @@ import { Component } from '@angular/core';
|
||||
<a routerLink="/login" routerLinkActive="active">Login</a>
|
||||
<a [routerLink]="[{ outlets: { popup: ['compose'] } }]">Contact</a>
|
||||
</nav>
|
||||
<router-outlet></router-outlet>
|
||||
<div [@routeAnimation]="getAnimationData(routerOutlet)">
|
||||
<router-outlet #routerOutlet="outlet"></router-outlet>
|
||||
</div>
|
||||
<router-outlet name="popup"></router-outlet>
|
||||
`
|
||||
`,
|
||||
animations: [ slideInAnimation ]
|
||||
// #enddocregion template
|
||||
})
|
||||
export class AppComponent {
|
||||
getAnimationData(outlet: RouterOutlet) {
|
||||
return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation'];
|
||||
}
|
||||
}
|
||||
|
@ -2,18 +2,11 @@
|
||||
import { Component, HostBinding } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { slideInDownAnimation } from './animations';
|
||||
|
||||
@Component({
|
||||
templateUrl: './compose-message.component.html',
|
||||
styles: [ ':host { position: relative; bottom: 10%; }' ],
|
||||
animations: [ slideInDownAnimation ]
|
||||
styles: [ ':host { position: relative; bottom: 10%; }' ]
|
||||
})
|
||||
export class ComposeMessageComponent {
|
||||
@HostBinding('@routeAnimation') routeAnimation = true;
|
||||
@HostBinding('style.display') display = 'block';
|
||||
@HostBinding('style.position') position = 'absolute';
|
||||
|
||||
details: string;
|
||||
message: string;
|
||||
sending = false;
|
||||
|
@ -5,7 +5,6 @@ import { ActivatedRoute, Router, ParamMap } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
import { switchMap } from 'rxjs/operators';
|
||||
|
||||
import { slideInDownAnimation } from '../animations';
|
||||
import { Crisis, CrisisService } from './crisis.service';
|
||||
import { DialogService } from '../dialog.service';
|
||||
|
||||
@ -25,14 +24,9 @@ import { DialogService } from '../dialog.service';
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
styles: ['input {width: 20em}'],
|
||||
animations: [ slideInDownAnimation ]
|
||||
styles: ['input {width: 20em}']
|
||||
})
|
||||
export class CrisisDetailComponent implements OnInit {
|
||||
@HostBinding('@routeAnimation') routeAnimation = true;
|
||||
@HostBinding('style.display') display = 'block';
|
||||
@HostBinding('style.position') position = 'absolute';
|
||||
|
||||
crisis: Crisis;
|
||||
editName: string;
|
||||
|
||||
|
@ -4,7 +4,6 @@ import { Component, OnInit, HostBinding } from '@angular/core';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { slideInDownAnimation } from '../animations';
|
||||
import { Crisis } from './crisis.service';
|
||||
import { DialogService } from '../dialog.service';
|
||||
|
||||
@ -24,14 +23,9 @@ import { DialogService } from '../dialog.service';
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
styles: ['input {width: 20em}'],
|
||||
animations: [ slideInDownAnimation ]
|
||||
styles: ['input {width: 20em}']
|
||||
})
|
||||
export class CrisisDetailComponent implements OnInit {
|
||||
@HostBinding('@routeAnimation') routeAnimation = true;
|
||||
@HostBinding('style.display') display = 'block';
|
||||
@HostBinding('style.position') position = 'absolute';
|
||||
|
||||
crisis: Crisis;
|
||||
editName: string;
|
||||
|
||||
|
@ -7,8 +7,6 @@ import { Component, OnInit, HostBinding } from '@angular/core';
|
||||
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
import { slideInDownAnimation } from '../animations';
|
||||
|
||||
import { Hero, HeroService } from './hero.service';
|
||||
|
||||
@Component({
|
||||
@ -26,16 +24,9 @@ import { Hero, HeroService } from './hero.service';
|
||||
<button (click)="gotoHeroes(hero)">Back</button>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
animations: [ slideInDownAnimation ]
|
||||
`
|
||||
})
|
||||
export class HeroDetailComponent implements OnInit {
|
||||
// #docregion host-bindings
|
||||
@HostBinding('@routeAnimation') routeAnimation = true;
|
||||
@HostBinding('style.display') display = 'block';
|
||||
@HostBinding('style.position') position = 'absolute';
|
||||
// #enddocregion host-bindings
|
||||
|
||||
hero$: Observable<Hero>;
|
||||
|
||||
// #docregion ctor
|
||||
|
@ -0,0 +1,22 @@
|
||||
// #docregion
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import { HeroListComponent } from './hero-list.component';
|
||||
import { HeroDetailComponent } from './hero-detail.component';
|
||||
|
||||
const heroesRoutes: Routes = [
|
||||
{ path: 'heroes', component: HeroListComponent, data: { animation: 'heroes' } },
|
||||
{ path: 'hero/:id', component: HeroDetailComponent, data: { animation: 'hero' } }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild(heroesRoutes)
|
||||
],
|
||||
exports: [
|
||||
RouterModule
|
||||
]
|
||||
})
|
||||
export class HeroRoutingModule { }
|
||||
// #enddocregion
|
@ -8,8 +8,8 @@ import { HeroDetailComponent } from './hero-detail.component';
|
||||
const heroesRoutes: Routes = [
|
||||
{ path: 'heroes', redirectTo: '/superheroes' },
|
||||
{ path: 'hero/:id', redirectTo: '/superhero/:id' },
|
||||
{ path: 'superheroes', component: HeroListComponent },
|
||||
{ path: 'superhero/:id', component: HeroDetailComponent }
|
||||
{ path: 'superheroes', component: HeroListComponent, data: { animation: 'heroes' } },
|
||||
{ path: 'superhero/:id', component: HeroDetailComponent, data: { animation: 'hero' } }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
Reference in New Issue
Block a user