mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 18:54:11 +08:00
test(angular): add support for multi-version testing (#25665)
This commit is contained in:
@ -0,0 +1,17 @@
|
||||
<ion-content>
|
||||
<ion-button id="dismiss" (click)="modal.dismiss()">Dismiss Modal</ion-button>
|
||||
<ion-accordion-group [value]="'a'">
|
||||
<ion-accordion value="a">
|
||||
<ion-item slot="header">
|
||||
<ion-label>A</ion-label>
|
||||
</ion-item>
|
||||
<div slot="content">A content</div>
|
||||
</ion-accordion>
|
||||
<ion-accordion value="b">
|
||||
<ion-item slot="header">
|
||||
<ion-label>B</ion-label>
|
||||
</ion-item>
|
||||
<div slot="content">B content</div>
|
||||
</ion-accordion>
|
||||
</ion-accordion-group>
|
||||
</ion-content>
|
@ -0,0 +1,11 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-accordion-modal',
|
||||
templateUrl: './accordion-modal.component.html',
|
||||
})
|
||||
export class AccordionModalComponent {
|
||||
modal: HTMLIonModalElement;
|
||||
|
||||
constructor() {}
|
||||
}
|
13
angular/test/base/src/app/accordion/accordion.component.html
Normal file
13
angular/test/base/src/app/accordion/accordion.component.html
Normal file
@ -0,0 +1,13 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons>
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>
|
||||
Accordion test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-button id="open-modal" (click)="open()">Open Modal</ion-button>
|
||||
</ion-content>
|
22
angular/test/base/src/app/accordion/accordion.component.ts
Normal file
22
angular/test/base/src/app/accordion/accordion.component.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ModalController } from '@ionic/angular';
|
||||
import { AccordionModalComponent } from './accordion-modal/accordion-modal.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-accordion',
|
||||
templateUrl: './accordion.component.html',
|
||||
})
|
||||
export class AccordionComponent {
|
||||
|
||||
constructor(
|
||||
private modalCtrl: ModalController
|
||||
) { }
|
||||
|
||||
async open() {
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: AccordionModalComponent,
|
||||
animated: false,
|
||||
});
|
||||
await modal.present();
|
||||
}
|
||||
}
|
13
angular/test/base/src/app/alert/alert.component.html
Normal file
13
angular/test/base/src/app/alert/alert.component.html
Normal file
@ -0,0 +1,13 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons>
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>
|
||||
Alert test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
|
||||
</ion-content>
|
39
angular/test/base/src/app/alert/alert.component.ts
Normal file
39
angular/test/base/src/app/alert/alert.component.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
import { AlertController } from '@ionic/angular';
|
||||
import { NavComponent } from '../nav/nav.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-alert',
|
||||
templateUrl: './alert.component.html',
|
||||
})
|
||||
export class AlertComponent {
|
||||
|
||||
changes = 0;
|
||||
|
||||
constructor(
|
||||
private alertCtrl: AlertController
|
||||
) { }
|
||||
|
||||
counter() {
|
||||
this.changes++;
|
||||
return Math.floor(this.changes / 2);
|
||||
}
|
||||
|
||||
async openAlert() {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: 'Hello',
|
||||
message: 'Some text',
|
||||
buttons: [
|
||||
{
|
||||
role: 'cancel',
|
||||
text: 'Cancel',
|
||||
handler: () => {
|
||||
console.log(NgZone.isInAngularZone());
|
||||
NgZone.assertInAngularZone();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
await alert.present();
|
||||
}
|
||||
}
|
78
angular/test/base/src/app/app-routing.module.ts
Normal file
78
angular/test/base/src/app/app-routing.module.ts
Normal file
@ -0,0 +1,78 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { InputsComponent } from './inputs/inputs.component';
|
||||
import { ModalComponent } from './modal/modal.component';
|
||||
import { RouterLinkComponent } from './router-link/router-link.component';
|
||||
import { RouterLinkPageComponent } from './router-link-page/router-link-page.component';
|
||||
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from './home-page/home-page.component';
|
||||
import { VirtualScrollComponent } from './virtual-scroll/virtual-scroll.component';
|
||||
import { VirtualScrollDetailComponent } from './virtual-scroll-detail/virtual-scroll-detail.component';
|
||||
import { NestedOutletComponent } from './nested-outlet/nested-outlet.component';
|
||||
import { NestedOutletPageComponent } from './nested-outlet-page/nested-outlet-page.component';
|
||||
import { NestedOutletPage2Component } from './nested-outlet-page2/nested-outlet-page2.component';
|
||||
import { ViewChildComponent } from './view-child/view-child.component';
|
||||
import { ProvidersComponent } from './providers/providers.component';
|
||||
import { SlidesComponent } from './slides/slides.component';
|
||||
import { FormComponent } from './form/form.component';
|
||||
import { NavigationPage1Component } from './navigation-page1/navigation-page1.component';
|
||||
import { NavigationPage2Component } from './navigation-page2/navigation-page2.component';
|
||||
import { NavigationPage3Component } from './navigation-page3/navigation-page3.component';
|
||||
import { AlertComponent } from './alert/alert.component';
|
||||
import { AccordionComponent } from './accordion/accordion.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: HomePageComponent },
|
||||
{ path: 'version-test', loadChildren: () => import('./version-test').then(m => m.VersionTestModule) },
|
||||
{ path: 'accordions', component: AccordionComponent },
|
||||
{ path: 'alerts', component: AlertComponent },
|
||||
{ path: 'inputs', component: InputsComponent },
|
||||
{ path: 'form', component: FormComponent },
|
||||
{ path: 'modals', component: ModalComponent },
|
||||
{ path: 'modal-inline', loadChildren: () => import('./modal-inline').then(m => m.ModalInlineModule) },
|
||||
{ path: 'view-child', component: ViewChildComponent },
|
||||
{ path: 'keep-contents-mounted', loadChildren: () => import('./keep-contents-mounted').then(m => m.OverlayAutoMountModule) },
|
||||
{ path: 'popover-inline', loadChildren: () => import('./popover-inline').then(m => m.PopoverInlineModule) },
|
||||
{ path: 'providers', component: ProvidersComponent },
|
||||
{ path: 'router-link', component: RouterLinkComponent },
|
||||
{ path: 'router-link-page', component: RouterLinkPageComponent },
|
||||
{ path: 'router-link-page2/:id', component: RouterLinkPage2Component },
|
||||
{ path: 'router-link-page3', component: RouterLinkPage3Component },
|
||||
{ path: 'slides', component: SlidesComponent },
|
||||
{ path: 'virtual-scroll', component: VirtualScrollComponent },
|
||||
{ path: 'virtual-scroll-detail/:itemId', component: VirtualScrollDetailComponent },
|
||||
{ path: 'tabs', redirectTo: '/tabs/account', pathMatch: 'full' },
|
||||
{
|
||||
path: 'navigation',
|
||||
children: [
|
||||
{ path: 'page1', component: NavigationPage1Component },
|
||||
{ path: 'page2', component: NavigationPage2Component },
|
||||
{ path: 'page3', component: NavigationPage3Component }
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
loadChildren: () => import('./tabs/tabs.module').then(m => m.TabsPageModule)
|
||||
},
|
||||
{
|
||||
path: 'nested-outlet',
|
||||
component: NestedOutletComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'page',
|
||||
component: NestedOutletPageComponent
|
||||
},
|
||||
{
|
||||
path: 'page2',
|
||||
component: NestedOutletPage2Component
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AppRoutingModule { }
|
0
angular/test/base/src/app/app.component.css
Normal file
0
angular/test/base/src/app/app.component.css
Normal file
3
angular/test/base/src/app/app.component.html
Normal file
3
angular/test/base/src/app/app.component.html
Normal file
@ -0,0 +1,3 @@
|
||||
<ion-app>
|
||||
<ion-router-outlet></ion-router-outlet>
|
||||
</ion-app>
|
9
angular/test/base/src/app/app.component.ts
Normal file
9
angular/test/base/src/app/app.component.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.css']
|
||||
})
|
||||
export class AppComponent {
|
||||
}
|
77
angular/test/base/src/app/app.module.ts
Normal file
77
angular/test/base/src/app/app.module.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
import { RouteReuseStrategy } from '@angular/router';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { InputsComponent } from './inputs/inputs.component';
|
||||
import { ModalComponent } from './modal/modal.component';
|
||||
import { ModalExampleComponent } from './modal-example/modal-example.component';
|
||||
import { RouterLinkComponent } from './router-link/router-link.component';
|
||||
import { RouterLinkPageComponent } from './router-link-page/router-link-page.component';
|
||||
import { RouterLinkPage2Component } from './router-link-page2/router-link-page2.component';
|
||||
import { RouterLinkPage3Component } from './router-link-page3/router-link-page3.component';
|
||||
import { HomePageComponent } from './home-page/home-page.component';
|
||||
import { VirtualScrollComponent } from './virtual-scroll/virtual-scroll.component';
|
||||
import { VirtualScrollDetailComponent } from './virtual-scroll-detail/virtual-scroll-detail.component';
|
||||
import { VirtualScrollInnerComponent } from './virtual-scroll-inner/virtual-scroll-inner.component';
|
||||
import { NestedOutletComponent } from './nested-outlet/nested-outlet.component';
|
||||
import { NestedOutletPageComponent } from './nested-outlet-page/nested-outlet-page.component';
|
||||
import { NestedOutletPage2Component } from './nested-outlet-page2/nested-outlet-page2.component';
|
||||
import { NavComponent } from './nav/nav.component';
|
||||
import { ViewChildComponent } from './view-child/view-child.component';
|
||||
import { ProvidersComponent } from './providers/providers.component';
|
||||
import { SlidesComponent } from './slides/slides.component';
|
||||
import { FormComponent } from './form/form.component';
|
||||
import { NavigationPage1Component } from './navigation-page1/navigation-page1.component';
|
||||
import { NavigationPage2Component } from './navigation-page2/navigation-page2.component';
|
||||
import { NavigationPage3Component } from './navigation-page3/navigation-page3.component';
|
||||
import { AlertComponent } from './alert/alert.component';
|
||||
import { AccordionComponent } from './accordion/accordion.component';
|
||||
import { AccordionModalComponent } from './accordion/accordion-modal/accordion-modal.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
InputsComponent,
|
||||
ModalComponent,
|
||||
ModalExampleComponent,
|
||||
RouterLinkComponent,
|
||||
RouterLinkPageComponent,
|
||||
RouterLinkPage2Component,
|
||||
RouterLinkPage3Component,
|
||||
HomePageComponent,
|
||||
VirtualScrollComponent,
|
||||
VirtualScrollDetailComponent,
|
||||
VirtualScrollInnerComponent,
|
||||
NestedOutletComponent,
|
||||
NestedOutletPageComponent,
|
||||
NestedOutletPage2Component,
|
||||
NavComponent,
|
||||
ViewChildComponent,
|
||||
ProvidersComponent,
|
||||
SlidesComponent,
|
||||
FormComponent,
|
||||
NavigationPage1Component,
|
||||
NavigationPage2Component,
|
||||
NavigationPage3Component,
|
||||
AlertComponent,
|
||||
AccordionComponent,
|
||||
AccordionModalComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||
AppRoutingModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
IonicModule.forRoot({ keyboardHeight: 12345 }),
|
||||
],
|
||||
providers: [
|
||||
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
15
angular/test/base/src/app/app.server.module.ts
Normal file
15
angular/test/base/src/app/app.server.module.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { ServerModule } from '@angular/platform-server';
|
||||
import { IonicServerModule } from '@ionic/angular-server';
|
||||
import { AppModule } from './app.module';
|
||||
import { AppComponent } from './app.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
AppModule,
|
||||
ServerModule,
|
||||
IonicServerModule
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppServerModule {}
|
83
angular/test/base/src/app/form/form.component.html
Normal file
83
angular/test/base/src/app/form/form.component.html
Normal file
@ -0,0 +1,83 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Forms test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<form [formGroup]="profileForm" (ngSubmit)="onSubmit($event)">
|
||||
<ion-list>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>DateTime</ion-label>
|
||||
<ion-datetime formControlName="datetime" min="1994-03-14" max="2017-12-09" display-format="MM/DD/YYYY">
|
||||
</ion-datetime>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Select</ion-label>
|
||||
<ion-select formControlName="select">
|
||||
<ion-select-option value="">No Game Console</ion-select-option>
|
||||
<ion-select-option value="nes">NES</ion-select-option>
|
||||
<ion-select-option value="n64" selected>Nintendo64</ion-select-option>
|
||||
<ion-select-option value="ps">PlayStation</ion-select-option>
|
||||
<ion-select-option value="genesis">Sega Genesis</ion-select-option>
|
||||
<ion-select-option value="saturn">Sega Saturn</ion-select-option>
|
||||
<ion-select-option value="snes">SNES</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Toggle</ion-label>
|
||||
<ion-toggle formControlName="toggle" slot="end"></ion-toggle>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Input (required)</ion-label>
|
||||
<ion-input formControlName="input" class="required" id="touched-input-test"></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-button id="input-touched" (click)="setTouched()">Set Input Touched</ion-button>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Input</ion-label>
|
||||
<ion-input formControlName="input2"></ion-input>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Checkbox</ion-label>
|
||||
<ion-checkbox formControlName="checkbox" slot="start"></ion-checkbox>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Range</ion-label>
|
||||
<ion-range formControlName="range"></ion-range>
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
<p>
|
||||
Form Status: <span id="status">{{ profileForm.status }}</span>
|
||||
</p>
|
||||
<p>
|
||||
Form Status: <span id="data">{{ profileForm.value | json }}</span>
|
||||
</p>
|
||||
<p>
|
||||
Form Submit: <span id="submit">{{submitted}}</span>
|
||||
</p>
|
||||
<ion-button id="mark-all-touched-button" (click)="markAllAsTouched()">Mark all as touched</ion-button>
|
||||
<ion-button id="submit-button" type="submit" [disabled]="!profileForm.valid">Submit</ion-button>
|
||||
|
||||
</form>
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Outside form</ion-label>
|
||||
<ion-toggle [formControl]="outsideToggle"></ion-toggle>
|
||||
<ion-note slot="end">{{outsideToggle.value}}</ion-note>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<p>
|
||||
<ion-button (click)="setValues()" id="set-values">Set values</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
53
angular/test/base/src/app/form/form.component.ts
Normal file
53
angular/test/base/src/app/form/form.component.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { UntypedFormGroup, UntypedFormBuilder, Validators, UntypedFormControl } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'app-form',
|
||||
templateUrl: './form.component.html',
|
||||
})
|
||||
export class FormComponent {
|
||||
|
||||
submitted = 'false';
|
||||
profileForm: UntypedFormGroup;
|
||||
outsideToggle = new UntypedFormControl(true);
|
||||
|
||||
constructor(fb: UntypedFormBuilder) {
|
||||
this.profileForm = fb.group({
|
||||
datetime: ['2010-08-20', Validators.required],
|
||||
select: [undefined, Validators.required],
|
||||
toggle: [false],
|
||||
input: ['', Validators.required],
|
||||
input2: ['Default Value'],
|
||||
checkbox: [false],
|
||||
range: [5, Validators.min(10)],
|
||||
}, {
|
||||
updateOn: typeof (window as any) !== 'undefined' && window.location.hash === '#blur' ? 'blur' : 'change'
|
||||
});
|
||||
}
|
||||
|
||||
setTouched() {
|
||||
const formControl = this.profileForm.get('input');
|
||||
formControl.markAsTouched();
|
||||
}
|
||||
|
||||
onSubmit(_ev) {
|
||||
this.submitted = 'true';
|
||||
}
|
||||
|
||||
setValues() {
|
||||
this.profileForm.patchValue({
|
||||
datetime: '2010-08-20',
|
||||
select: 'nes',
|
||||
toggle: true,
|
||||
input: 'Some value',
|
||||
input2: 'Another values',
|
||||
checkbox: true,
|
||||
range: 50
|
||||
});
|
||||
}
|
||||
|
||||
markAllAsTouched() {
|
||||
this.profileForm.markAllAsTouched();
|
||||
}
|
||||
|
||||
}
|
71
angular/test/base/src/app/home-page/home-page.component.html
Normal file
71
angular/test/base/src/app/home-page/home-page.component.html
Normal file
@ -0,0 +1,71 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Test App
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item routerLink="/alerts" [routerAnimation]="routerAnimation">
|
||||
<ion-label>
|
||||
Alerts test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/inputs">
|
||||
<ion-label>
|
||||
Inputs test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/form">
|
||||
<ion-label>
|
||||
Form test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/modals">
|
||||
<ion-label>
|
||||
Modals test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/router-link">
|
||||
<ion-label>
|
||||
Router link test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/tabs">
|
||||
<ion-label>
|
||||
Tabs test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/slides">
|
||||
<ion-label>
|
||||
Slides test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/virtual-scroll">
|
||||
<ion-label>
|
||||
Virtual Scroll
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/nested-outlet/page">
|
||||
<ion-label>
|
||||
Nested ion-router-outlet
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/view-child">
|
||||
<ion-label>
|
||||
ViewChild()
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/providers">
|
||||
<ion-label>
|
||||
Providers
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item routerLink="/accordions">
|
||||
<ion-label>
|
||||
Accordions Test
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
25
angular/test/base/src/app/home-page/home-page.component.ts
Normal file
25
angular/test/base/src/app/home-page/home-page.component.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { AnimationBuilder, AnimationController } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home-page',
|
||||
templateUrl: './home-page.component.html',
|
||||
})
|
||||
export class HomePageComponent {
|
||||
routerAnimation: AnimationBuilder = (_, opts) => {
|
||||
const { direction, enteringEl, leavingEl } = opts;
|
||||
const animation = this.animationCtrl.create().duration(500).easing('ease-out');
|
||||
const enteringAnimation = this.animationCtrl.create().addElement(enteringEl).beforeRemoveClass(['ion-page-invisible']);
|
||||
const leavingAnimation = this.animationCtrl.create().addElement(leavingEl).beforeRemoveClass(['ion-page-invisible']);
|
||||
if (direction === 'back') {
|
||||
enteringAnimation.fromTo('transform', 'translateX(-100%)', 'translateX(0%)');
|
||||
leavingAnimation.fromTo('transform', 'translateX(0%)', 'translateX(100%)');
|
||||
} else {
|
||||
enteringAnimation.fromTo('transform', 'translateX(100%)', 'translateX(0%)');
|
||||
leavingAnimation.fromTo('transform', 'translateX(0%)', 'translateX(-100%)');
|
||||
}
|
||||
return animation.addAnimation([enteringAnimation, leavingAnimation]);
|
||||
};
|
||||
|
||||
constructor(private animationCtrl: AnimationController) {}
|
||||
}
|
107
angular/test/base/src/app/inputs/inputs.component.html
Normal file
107
angular/test/base/src/app/inputs/inputs.component.html
Normal file
@ -0,0 +1,107 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Inputs test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
|
||||
<ion-list>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>DateTime</ion-label>
|
||||
<ion-datetime [(ngModel)]="datetime" min="1994-03-14" max="2017-12-09" display-format="MM/DD/YYYY"></ion-datetime>
|
||||
<ion-note slot="end" id="datetime-note">{{datetime}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item color="dark">
|
||||
<ion-label>DateTime Mirror</ion-label>
|
||||
<ion-datetime [(ngModel)]="datetime" min="1994-03-14" max="2017-12-09" display-format="MM/DD/YYYY"></ion-datetime>
|
||||
<ion-note slot="end">{{datetime}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Select</ion-label>
|
||||
<ion-select [(ngModel)]="select">
|
||||
<ion-select-option value="">No Game Console</ion-select-option>
|
||||
<ion-select-option value="nes">NES</ion-select-option>
|
||||
<ion-select-option value="n64" selected>Nintendo64</ion-select-option>
|
||||
<ion-select-option value="ps">PlayStation</ion-select-option>
|
||||
<ion-select-option value="genesis">Sega Genesis</ion-select-option>
|
||||
<ion-select-option value="saturn">Sega Saturn</ion-select-option>
|
||||
<ion-select-option value="snes">SNES</ion-select-option>
|
||||
</ion-select>
|
||||
<ion-note slot="end" id="select-note">{{select}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item color="dark">
|
||||
<ion-label>Select Mirror</ion-label>
|
||||
<ion-select [(ngModel)]="select">
|
||||
<ion-select-option value="">No Game Console</ion-select-option>
|
||||
<ion-select-option value="nes">NES</ion-select-option>
|
||||
<ion-select-option value="n64" selected>Nintendo64</ion-select-option>
|
||||
<ion-select-option value="ps">PlayStation</ion-select-option>
|
||||
<ion-select-option value="genesis">Sega Genesis</ion-select-option>
|
||||
<ion-select-option value="saturn">Sega Saturn</ion-select-option>
|
||||
<ion-select-option value="snes">SNES</ion-select-option>
|
||||
</ion-select>
|
||||
<ion-note slot="end">{{select}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Toggle</ion-label>
|
||||
<ion-toggle [(ngModel)]="toggle" slot="end"></ion-toggle>
|
||||
<ion-note slot="end" id="toggle-note">{{toggle}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item color="dark">
|
||||
<ion-label>Toggle Mirror</ion-label>
|
||||
<ion-toggle [(ngModel)]="toggle" slot="end"></ion-toggle>
|
||||
<ion-note slot="end">{{toggle}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Input</ion-label>
|
||||
<ion-input [(ngModel)]="input"></ion-input>
|
||||
<ion-note slot="end" id="input-note">{{input}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item color="dark">
|
||||
<ion-label>Input Mirror</ion-label>
|
||||
<ion-input [(ngModel)]="input"></ion-input>
|
||||
<ion-note slot="end">{{input}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Checkbox</ion-label>
|
||||
<ion-checkbox [(ngModel)]="checkbox" slot="start"></ion-checkbox>
|
||||
<ion-note slot="end" id="checkbox-note">{{checkbox}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item color="dark">
|
||||
<ion-label>Checkbox Mirror</ion-label>
|
||||
<ion-checkbox [(ngModel)]="checkbox" slot="start"></ion-checkbox>
|
||||
<ion-note slot="end">{{checkbox}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-label>Range</ion-label>
|
||||
<ion-range [(ngModel)]="range"></ion-range>
|
||||
<ion-note slot="end" id="range-note">{{range}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
<ion-item color="dark">
|
||||
<ion-label>Range Mirror</ion-label>
|
||||
<ion-range [(ngModel)]="range">
|
||||
<ion-toggle slot="start" id="nested-toggle" [(ngModel)]="toggle"></ion-toggle>
|
||||
</ion-range>
|
||||
<ion-note slot="end">{{range}}</ion-note>
|
||||
</ion-item>
|
||||
|
||||
</ion-list>
|
||||
<p>
|
||||
<ion-button (click)="setValues()" id="set-button">Set values</ion-button>
|
||||
<ion-button (click)="resetValues()" id="reset-button">Reset values</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
40
angular/test/base/src/app/inputs/inputs.component.ts
Normal file
40
angular/test/base/src/app/inputs/inputs.component.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-inputs',
|
||||
templateUrl: './inputs.component.html',
|
||||
})
|
||||
export class InputsComponent {
|
||||
|
||||
datetime = '1994-03-15';
|
||||
input = 'some text';
|
||||
checkbox = true;
|
||||
toggle = true;
|
||||
select = 'nes';
|
||||
range = 10;
|
||||
changes = 0;
|
||||
|
||||
setValues() {
|
||||
console.log('set values');
|
||||
this.datetime = '1994-03-15';
|
||||
this.input = 'some text';
|
||||
this.checkbox = true;
|
||||
this.toggle = true;
|
||||
this.select = 'nes';
|
||||
this.range = 10;
|
||||
}
|
||||
|
||||
resetValues() {
|
||||
console.log('reset values');
|
||||
this.datetime = undefined;
|
||||
this.input = undefined;
|
||||
this.checkbox = false;
|
||||
this.toggle = false;
|
||||
this.select = undefined;
|
||||
this.range = undefined;
|
||||
}
|
||||
counter() {
|
||||
this.changes++;
|
||||
return Math.floor(this.changes / 2);
|
||||
}
|
||||
}
|
2
angular/test/base/src/app/keep-contents-mounted/index.ts
Normal file
2
angular/test/base/src/app/keep-contents-mounted/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './keep-contents-mounted.component';
|
||||
export * from './keep-contents-mounted.module';
|
@ -0,0 +1,16 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { OverlayKeepContentsMounted } from ".";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: OverlayKeepContentsMounted
|
||||
}
|
||||
])
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class OverlayKeepContentsMountedRoutingModule { }
|
@ -0,0 +1,22 @@
|
||||
<ion-content>
|
||||
<ion-button id="open-modal" (click)="modal.present()">Open Modal</ion-button>
|
||||
<ion-button id="open-popover" (click)="popover.present()">Open Popover</ion-button>
|
||||
|
||||
<ion-modal [keepContentsMounted]="true" #modal>
|
||||
<ng-template>
|
||||
<ion-content>
|
||||
<ion-button (click)="modal.dismiss()">Dismiss</ion-button>
|
||||
Modal Content
|
||||
</ion-content>
|
||||
</ng-template>
|
||||
</ion-modal>
|
||||
|
||||
<ion-popover [keepContentsMounted]="true" #popover>
|
||||
<ng-template>
|
||||
<ion-content>
|
||||
<ion-button (click)="popover.dismiss()">Dismiss</ion-button>
|
||||
Popover Content
|
||||
</ion-content>
|
||||
</ng-template>
|
||||
</ion-popover>
|
||||
</ion-content>
|
@ -0,0 +1,13 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
/**
|
||||
* Validates that inline modals correctly mount
|
||||
* inner components when keepContentsMounted is
|
||||
* enabled.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-keep-contents-mounted',
|
||||
templateUrl: 'keep-contents-mounted.component.html'
|
||||
})
|
||||
export class OverlayKeepContentsMounted {
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { NgModule } from "@angular/core";
|
||||
import { IonicModule } from "@ionic/angular";
|
||||
import { OverlayKeepContentsMountedRoutingModule } from "./keep-contents-mounted-routing.module";
|
||||
import { OverlayKeepContentsMounted } from "./keep-contents-mounted.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, IonicModule, OverlayKeepContentsMountedRoutingModule],
|
||||
declarations: [OverlayKeepContentsMounted],
|
||||
exports: [OverlayKeepContentsMounted]
|
||||
})
|
||||
export class OverlayAutoMountModule { }
|
@ -0,0 +1,35 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button (click)="closeModal()" id="close-modal">
|
||||
Close
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Value</h1>
|
||||
<h2>{{value}}</h2>
|
||||
<h3>{{valueFromParams}}</h3>
|
||||
<p>modal is defined: <span id="modalInstance">{{ !!modal }}</span></p>
|
||||
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
|
||||
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
|
||||
<p>ionViewDidEnter: <span id="ionViewDidEnter">{{didEnter}}</span></p>
|
||||
<p>ionViewWillLeave: <span id="ionViewWillLeave">{{willLeave}}</span></p>
|
||||
<p>ionViewDidLeave: <span id="ionViewDidLeave">{{didLeave}}</span></p>
|
||||
<p *ngIf="!!nav">
|
||||
<ion-button (click)="push()" class="push-page">Push page</ion-button>
|
||||
<ion-button (click)="pop()" class="pop-page">Pop page</ion-button>
|
||||
</p>
|
||||
|
||||
<form [formGroup]="form">
|
||||
<ion-item id="inputWithFloatingLabel">
|
||||
<ion-label color="primary" position="floating">Floating Label</ion-label>
|
||||
<ion-select multiple="false" formControlName="select">
|
||||
<ion-select-option [value]="0">Option 0</ion-select-option>
|
||||
<ion-select-option [value]="1">Option 1</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
</form>
|
||||
</ion-content>
|
@ -0,0 +1,70 @@
|
||||
import { Component, Input, NgZone, OnInit, Optional } from '@angular/core';
|
||||
import { UntypedFormControl, UntypedFormGroup } from '@angular/forms';
|
||||
import { ModalController, NavParams, IonNav, ViewWillLeave, ViewDidEnter, ViewDidLeave } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-modal-example',
|
||||
templateUrl: './modal-example.component.html',
|
||||
})
|
||||
export class ModalExampleComponent implements OnInit, ViewWillLeave, ViewDidEnter, ViewWillLeave, ViewDidLeave {
|
||||
|
||||
@Input() value: string;
|
||||
|
||||
form = new UntypedFormGroup({
|
||||
select: new UntypedFormControl([])
|
||||
});
|
||||
|
||||
valueFromParams: string;
|
||||
onInit = 0;
|
||||
willEnter = 0;
|
||||
didEnter = 0;
|
||||
willLeave = 0;
|
||||
didLeave = 0;
|
||||
|
||||
modal: HTMLElement;
|
||||
|
||||
constructor(
|
||||
private modalCtrl: ModalController,
|
||||
@Optional() public nav: IonNav,
|
||||
navParams: NavParams
|
||||
) {
|
||||
this.valueFromParams = navParams.get('prop');
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.onInit++;
|
||||
}
|
||||
|
||||
ionViewWillEnter() {
|
||||
if (this.onInit !== 1) {
|
||||
throw new Error('ngOnInit was not called');
|
||||
}
|
||||
NgZone.assertInAngularZone();
|
||||
this.willEnter++;
|
||||
}
|
||||
ionViewDidEnter() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.didEnter++;
|
||||
}
|
||||
ionViewWillLeave() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.willLeave++;
|
||||
}
|
||||
ionViewDidLeave() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.didLeave++;
|
||||
}
|
||||
closeModal() {
|
||||
this.modalCtrl.dismiss();
|
||||
}
|
||||
|
||||
push() {
|
||||
this.nav.push(ModalExampleComponent, {
|
||||
'value': 'pushed!'
|
||||
});
|
||||
}
|
||||
pop() {
|
||||
this.nav.pop();
|
||||
}
|
||||
}
|
2
angular/test/base/src/app/modal-inline/index.ts
Normal file
2
angular/test/base/src/app/modal-inline/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './modal-inline.component';
|
||||
export * from './modal-inline.module';
|
@ -0,0 +1,16 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { ModalInlineComponent } from ".";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: ModalInlineComponent
|
||||
}
|
||||
])
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class ModalInlineRoutingModule { }
|
@ -0,0 +1,20 @@
|
||||
<ion-button id="open-modal">Open Modal</ion-button>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
breakpointDidChange event count: <span id="breakpointDidChange">{{ breakpointDidChangeCounter }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ion-modal [animated]="false" trigger="open-modal" [breakpoints]="[0.1, 0.5, 1]" [initialBreakpoint]="0.5"
|
||||
(ionBreakpointDidChange)="onBreakpointDidChange()">
|
||||
<ng-template>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item *ngFor="let item of items">
|
||||
<ion-label>{{ item }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ng-template>
|
||||
</ion-modal>
|
@ -0,0 +1,27 @@
|
||||
import { AfterViewInit, Component } from "@angular/core";
|
||||
|
||||
/**
|
||||
* Validates that inline modals will correctly display
|
||||
* dynamic contents that are updated after the modal is
|
||||
* display.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-modal-inline',
|
||||
templateUrl: 'modal-inline.component.html'
|
||||
})
|
||||
export class ModalInlineComponent implements AfterViewInit {
|
||||
|
||||
items: string[] = [];
|
||||
|
||||
breakpointDidChangeCounter = 0;
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
setTimeout(() => {
|
||||
this.items = ['A', 'B', 'C', 'D'];
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
onBreakpointDidChange() {
|
||||
this.breakpointDidChangeCounter++;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { NgModule } from "@angular/core";
|
||||
import { IonicModule } from "@ionic/angular";
|
||||
import { ModalInlineRoutingModule } from "./modal-inline-routing.module";
|
||||
import { ModalInlineComponent } from "./modal-inline.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, IonicModule, ModalInlineRoutingModule],
|
||||
declarations: [ModalInlineComponent],
|
||||
exports: [ModalInlineComponent]
|
||||
})
|
||||
export class ModalInlineModule { }
|
17
angular/test/base/src/app/modal/modal.component.html
Normal file
17
angular/test/base/src/app/modal/modal.component.html
Normal file
@ -0,0 +1,17 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Modal test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button (click)="openModal()" id="action-button">Open Modal</ion-button>
|
||||
<ion-button (click)="openNav()" id="action-button-2">Open Nav in Modal</ion-button>
|
||||
<p>
|
||||
onWillDismiss: <span id="onWillDismiss">{{onWillDismiss}}</span>
|
||||
</p>
|
||||
<p>
|
||||
onDidDismiss: <span id="onDidDismiss">{{onDidDismiss}}</span>
|
||||
</p>
|
||||
</ion-content>
|
49
angular/test/base/src/app/modal/modal.component.ts
Normal file
49
angular/test/base/src/app/modal/modal.component.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
import { ModalController } from '@ionic/angular';
|
||||
import { ModalExampleComponent } from '../modal-example/modal-example.component';
|
||||
import { NavComponent } from '../nav/nav.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-modal',
|
||||
templateUrl: './modal.component.html',
|
||||
})
|
||||
export class ModalComponent {
|
||||
|
||||
onWillDismiss = false;
|
||||
onDidDismiss = false;
|
||||
|
||||
constructor(
|
||||
private modalCtrl: ModalController
|
||||
) { }
|
||||
|
||||
async openModal() {
|
||||
return this.open(ModalExampleComponent);
|
||||
}
|
||||
|
||||
async openNav() {
|
||||
return this.open(NavComponent);
|
||||
}
|
||||
|
||||
async open(TheModalComponent: any) {
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: TheModalComponent,
|
||||
animated: false,
|
||||
componentProps: {
|
||||
value: '123',
|
||||
prop: '321'
|
||||
}
|
||||
});
|
||||
await modal.present();
|
||||
modal.onWillDismiss().then(() => {
|
||||
NgZone.assertInAngularZone();
|
||||
this.onWillDismiss = true;
|
||||
});
|
||||
modal.onDidDismiss().then(() => {
|
||||
NgZone.assertInAngularZone();
|
||||
if (!this.onWillDismiss) {
|
||||
throw new Error('onWillDismiss should be emitted first');
|
||||
}
|
||||
this.onDidDismiss = true;
|
||||
});
|
||||
}
|
||||
}
|
1
angular/test/base/src/app/nav/nav.component.html
Normal file
1
angular/test/base/src/app/nav/nav.component.html
Normal file
@ -0,0 +1 @@
|
||||
<ion-nav [root]="rootPage" [rootParams]="rootParams"></ion-nav>
|
20
angular/test/base/src/app/nav/nav.component.ts
Normal file
20
angular/test/base/src/app/nav/nav.component.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { ModalExampleComponent } from '../modal-example/modal-example.component';
|
||||
import { NavParams } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nav',
|
||||
templateUrl: './nav.component.html',
|
||||
})
|
||||
export class NavComponent {
|
||||
rootPage = ModalExampleComponent;
|
||||
rootParams: any;
|
||||
|
||||
constructor(
|
||||
params: NavParams
|
||||
) {
|
||||
this.rootParams = {
|
||||
...params.data
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<p>
|
||||
navigation-page1 works!
|
||||
</p>
|
@ -0,0 +1,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { NavController } from '@ionic/angular';
|
||||
|
||||
let count = 0;
|
||||
@Component({
|
||||
selector: 'app-navigation-page1',
|
||||
templateUrl: './navigation-page1.component.html',
|
||||
})
|
||||
export class NavigationPage1Component {
|
||||
constructor(
|
||||
private navController: NavController
|
||||
) {}
|
||||
|
||||
ionViewDidEnter() {
|
||||
if (count < 1) {
|
||||
this.navController.navigateBack('/navigation/page2');
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<p>
|
||||
navigation-page2 works!
|
||||
</p>
|
@ -0,0 +1,17 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { NavController } from '@ionic/angular';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-navigation-page2',
|
||||
templateUrl: './navigation-page2.component.html',
|
||||
})
|
||||
export class NavigationPage2Component {
|
||||
constructor(
|
||||
private navController: NavController
|
||||
) {}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this.navController.navigateForward('/navigation/page1');
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<p>
|
||||
navigation-page3 works!
|
||||
</p>
|
@ -0,0 +1,16 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { NavController } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-navigation-page3',
|
||||
templateUrl: './navigation-page3.component.html',
|
||||
})
|
||||
export class NavigationPage3Component {
|
||||
constructor(
|
||||
private navController: NavController
|
||||
) {}
|
||||
|
||||
ionViewDidEnter() {
|
||||
this.navController.navigateRoot('/navigation/page2');
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<ion-content>
|
||||
<h1>Nested page 1</h1>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs" id="goto-tabs">Go To Tabs</ion-button>
|
||||
<ion-button routerLink="/nested-outlet/page2" id="goto-nested-page2">Go To SECOND</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
@ -0,0 +1,16 @@
|
||||
import { Component, NgZone, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nested-outlet-page',
|
||||
templateUrl: './nested-outlet-page.component.html',
|
||||
})
|
||||
export class NestedOutletPageComponent implements OnDestroy, OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
NgZone.assertInAngularZone();
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
<ion-content>
|
||||
<h1>Nested page 2</h1>
|
||||
<p>
|
||||
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go To FIRST</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
@ -0,0 +1,16 @@
|
||||
import { Component, NgZone, OnDestroy, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nested-outlet-page2',
|
||||
templateUrl: './nested-outlet-page2.component.html',
|
||||
})
|
||||
export class NestedOutletPage2Component implements OnDestroy, OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
NgZone.assertInAngularZone();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>
|
||||
NESTED OUTLET
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-router-outlet></ion-router-outlet>
|
||||
</ion-content>
|
@ -0,0 +1,9 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-nested-outlet',
|
||||
templateUrl: './nested-outlet.component.html',
|
||||
})
|
||||
export class NestedOutletComponent {
|
||||
|
||||
}
|
1
angular/test/base/src/app/popover-inline/index.ts
Normal file
1
angular/test/base/src/app/popover-inline/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './popover-inline.module';
|
@ -0,0 +1,14 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { PopoverInlineComponent } from "./popover-inline.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: PopoverInlineComponent
|
||||
}
|
||||
])],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class PopoverInlineRoutingModule { }
|
@ -0,0 +1,13 @@
|
||||
<ion-button (click)="openPopover(popover)">Open Popover</ion-button>
|
||||
|
||||
<ion-popover #popover>
|
||||
<ng-template>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-item *ngFor="let item of items">
|
||||
<ion-label>{{ item }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ng-template>
|
||||
</ion-popover>
|
@ -0,0 +1,24 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
/**
|
||||
* Validates that inline popovers will correctly display
|
||||
* dynamic contents that are updated after the modal is
|
||||
* display.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-popover-inline',
|
||||
templateUrl: 'popover-inline.component.html'
|
||||
})
|
||||
export class PopoverInlineComponent {
|
||||
|
||||
items: string[] = [];
|
||||
|
||||
openPopover(popover: HTMLIonPopoverElement) {
|
||||
popover.present();
|
||||
|
||||
setTimeout(() => {
|
||||
this.items = ['A', 'B', 'C', 'D'];
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { NgModule } from "@angular/core";
|
||||
import { IonicModule } from "@ionic/angular";
|
||||
import { PopoverInlineRoutingModule } from "./popover-inline-routing.module";
|
||||
import { PopoverInlineComponent } from "./popover-inline.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, IonicModule, PopoverInlineRoutingModule],
|
||||
declarations: [PopoverInlineComponent],
|
||||
})
|
||||
export class PopoverInlineModule { }
|
39
angular/test/base/src/app/providers/providers.component.html
Normal file
39
angular/test/base/src/app/providers/providers.component.html
Normal file
@ -0,0 +1,39 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Providers Test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<p>
|
||||
isLoaded: <span id="is-loaded">{{isLoaded}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isReady: <span id="is-ready">{{isReady}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isResumed: <span id="is-resumed">{{isResumed}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isPaused: <span id="is-paused">{{isPaused}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isResized: <span id="is-resized">{{isResized}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isTesting: <span id="is-testing">{{isTesting}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isDesktop: <span id="is-desktop">{{isDesktop}}</span>
|
||||
</p>
|
||||
<p>
|
||||
isMobile: <span id="is-mobile">{{isMobile}}</span>
|
||||
</p>
|
||||
<p>
|
||||
keyboardHeight: <span id="keyboard-height">{{keyboardHeight}}</span>
|
||||
</p>
|
||||
<p>
|
||||
queryParams: <span id="query-params">{{queryParams}}</span>
|
||||
</p>
|
||||
</ion-content>
|
85
angular/test/base/src/app/providers/providers.component.ts
Normal file
85
angular/test/base/src/app/providers/providers.component.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
import {
|
||||
Platform, ModalController, AlertController, ActionSheetController,
|
||||
PopoverController, ToastController, PickerController, MenuController,
|
||||
LoadingController, NavController, DomController, Config
|
||||
} from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-providers',
|
||||
templateUrl: './providers.component.html',
|
||||
})
|
||||
export class ProvidersComponent {
|
||||
|
||||
isLoaded = false;
|
||||
isReady = false;
|
||||
isResumed = false;
|
||||
isPaused = false;
|
||||
isResized = false;
|
||||
isTesting: boolean = undefined;
|
||||
isDesktop: boolean = undefined;
|
||||
isMobile: boolean = undefined;
|
||||
keyboardHeight = 0;
|
||||
queryParams = '';
|
||||
|
||||
constructor(
|
||||
actionSheetCtrl: ActionSheetController,
|
||||
alertCtrl: AlertController,
|
||||
loadingCtrl: LoadingController,
|
||||
menuCtrl: MenuController,
|
||||
pickerCtrl: PickerController,
|
||||
modalCtrl: ModalController,
|
||||
platform: Platform,
|
||||
popoverCtrl: PopoverController,
|
||||
toastCtrl: ToastController,
|
||||
navCtrl: NavController,
|
||||
domCtrl: DomController,
|
||||
config: Config,
|
||||
zone: NgZone
|
||||
) {
|
||||
// test all providers load
|
||||
if (
|
||||
actionSheetCtrl && alertCtrl && loadingCtrl && menuCtrl && pickerCtrl &&
|
||||
modalCtrl && platform && popoverCtrl && toastCtrl && navCtrl && domCtrl && config
|
||||
) {
|
||||
this.isLoaded = true;
|
||||
}
|
||||
|
||||
// test platform ready()
|
||||
platform.ready().then(() => {
|
||||
NgZone.assertInAngularZone();
|
||||
this.isReady = true;
|
||||
});
|
||||
platform.resume.subscribe(() => {
|
||||
console.log('platform:resume');
|
||||
NgZone.assertInAngularZone();
|
||||
this.isResumed = true;
|
||||
});
|
||||
platform.pause.subscribe(() => {
|
||||
console.log('platform:pause');
|
||||
NgZone.assertInAngularZone();
|
||||
this.isPaused = true;
|
||||
});
|
||||
platform.resize.subscribe(() => {
|
||||
console.log('platform:resize');
|
||||
NgZone.assertInAngularZone();
|
||||
this.isResized = true;
|
||||
});
|
||||
const firstQuery = platform.getQueryParam('firstParam');
|
||||
const secondQuery = platform.getQueryParam('secondParam');
|
||||
this.queryParams = `firstParam: ${firstQuery}, firstParam: ${secondQuery}`;
|
||||
|
||||
this.isDesktop = platform.is('desktop');
|
||||
this.isMobile = platform.is('mobile');
|
||||
|
||||
// test config
|
||||
this.isTesting = config.getBoolean('_testing');
|
||||
this.keyboardHeight = config.getNumber('keyboardHeight');
|
||||
|
||||
zone.runOutsideAngular(() => {
|
||||
document.dispatchEvent(new CustomEvent('pause'));
|
||||
document.dispatchEvent(new CustomEvent('resume'));
|
||||
window.dispatchEvent(new CustomEvent('resize'));
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>router-link page</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
|
||||
<p>canGoBack: <span id="canGoBack">{{canGoBack}}</span></p>
|
||||
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
|
||||
<p>ionViewDidEnter: <span id="ionViewDidEnter">{{didEnter}}</span></p>
|
||||
<p>ionViewWillLeave: <span id="ionViewWillLeave">{{willLeave}}</span></p>
|
||||
<p>ionViewDidLeave: <span id="ionViewDidLeave">{{didLeave}}</span></p>
|
||||
</ion-content>
|
@ -0,0 +1,52 @@
|
||||
import { Component, OnInit, NgZone } from '@angular/core';
|
||||
import { IonRouterOutlet, ViewDidEnter, ViewDidLeave, ViewWillLeave } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-router-link-page',
|
||||
templateUrl: './router-link-page.component.html',
|
||||
})
|
||||
export class RouterLinkPageComponent implements OnInit, ViewWillLeave, ViewDidEnter, ViewWillLeave, ViewDidLeave {
|
||||
|
||||
onInit = 0;
|
||||
willEnter = 0;
|
||||
didEnter = 0;
|
||||
willLeave = 0;
|
||||
didLeave = 0;
|
||||
canGoBack: boolean = null;
|
||||
|
||||
constructor(
|
||||
private ionRouterOutlet: IonRouterOutlet
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.canGoBack = this.ionRouterOutlet.canGoBack();
|
||||
this.onInit++;
|
||||
}
|
||||
|
||||
ionViewWillEnter() {
|
||||
if (this.onInit !== 1) {
|
||||
throw new Error('ngOnInit was not called');
|
||||
}
|
||||
if (this.canGoBack !== this.ionRouterOutlet.canGoBack()) {
|
||||
throw new Error('canGoBack() changed');
|
||||
}
|
||||
NgZone.assertInAngularZone();
|
||||
this.willEnter++;
|
||||
}
|
||||
ionViewDidEnter() {
|
||||
if (this.canGoBack !== this.ionRouterOutlet.canGoBack()) {
|
||||
throw new Error('canGoBack() changed');
|
||||
}
|
||||
NgZone.assertInAngularZone();
|
||||
this.didEnter++;
|
||||
}
|
||||
ionViewWillLeave() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.willLeave++;
|
||||
}
|
||||
ionViewDidLeave() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.didLeave++;
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Router Page 2</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button routerLink="/router-link-page3" id="goToPage3">Go to Page 3</ion-button>
|
||||
</ion-content>
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-router-link-page2',
|
||||
templateUrl: './router-link-page2.component.html'
|
||||
})
|
||||
export class RouterLinkPage2Component implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
console.log('ngOnInit')
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
<ion-header>
|
||||
<ion-toolbar color="dark">
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button defaultHref="/?token=ABC#fragment" id="goBackFromPage3"></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Router Page 3</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
Page 3
|
||||
</ion-content>
|
@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-router-link-page3',
|
||||
templateUrl: './router-link-page3.component.html'
|
||||
})
|
||||
export class RouterLinkPage3Component implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
console.log('ngOnInit')
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Router Link Test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
|
||||
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
|
||||
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
|
||||
<p>ionViewDidEnter: <span id="ionViewDidEnter">{{didEnter}}</span></p>
|
||||
<p>ionViewWillLeave: <span id="ionViewWillLeave">{{willLeave}}</span></p>
|
||||
<p>ionViewDidLeave: <span id="ionViewDidLeave">{{didLeave}}</span></p>
|
||||
<p>Change Detections: <span id="counter">{{counter()}}</span></p>
|
||||
|
||||
<p>
|
||||
<ion-button routerLink="/router-link-page" expand="block" color="dark" id="routerLink">ion-button[routerLink]
|
||||
</ion-button>
|
||||
<ion-button routerLink="/router-link-page" routerDirection="root" expand="block" color="dark" id="routerLink-root">
|
||||
ion-button[routerLink] (direction:root)</ion-button>
|
||||
<ion-button routerLink="/router-link-page" routerDirection="back" expand="block" color="dark" id="routerLink-back">
|
||||
ion-button[routerLink] (direction:back)</ion-button>
|
||||
</p>
|
||||
|
||||
<p><a [routerLink]="null">null router link</a></p>
|
||||
<p><a routerLink="/router-link-page" id="a">a[routerLink]</a></p>
|
||||
<p><a routerLink="/router-link-page" routerDirection="root" id="a-root">a[routerLink] (direction:root)</a></p>
|
||||
<p><a routerLink="/router-link-page" routerDirection="back" id="a-back">a[routerLink] (direction:back)</a></p>
|
||||
|
||||
<p><button (click)="navigate()" id="button">navigate</button></p>
|
||||
<p><button (click)="navigateForward()" id="button-forward">navigateForward</button></p>
|
||||
<p><button (click)="navigateRoot()" id="button-root">navigateForward</button></p>
|
||||
<p><button (click)="navigateBack()" id="button-back">navigateBack</button></p>
|
||||
|
||||
<p><button id="queryParamsFragment" routerLink="/router-link-page2/MyPageID==" [queryParams]="{ token: 'A&=#Y' }"
|
||||
fragment="myDiv1">Query Params and Fragment</button></p>
|
||||
|
||||
</ion-content>
|
@ -0,0 +1,68 @@
|
||||
import { Component, NgZone, OnInit } from '@angular/core';
|
||||
import { NavController, ViewDidEnter, ViewDidLeave, ViewWillEnter, ViewWillLeave } from '@ionic/angular';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-router-link',
|
||||
templateUrl: './router-link.component.html',
|
||||
})
|
||||
export class RouterLinkComponent implements OnInit, ViewWillEnter, ViewDidEnter, ViewWillLeave, ViewDidLeave {
|
||||
|
||||
onInit = 0;
|
||||
willEnter = 0;
|
||||
didEnter = 0;
|
||||
willLeave = 0;
|
||||
didLeave = 0;
|
||||
changes = 0;
|
||||
|
||||
constructor(
|
||||
private navCtrl: NavController,
|
||||
private router: Router
|
||||
) {}
|
||||
|
||||
navigate() {
|
||||
this.router.navigateByUrl('/router-link-page');
|
||||
}
|
||||
|
||||
navigateForward() {
|
||||
this.navCtrl.navigateForward('/router-link-page');
|
||||
}
|
||||
|
||||
navigateBack() {
|
||||
this.navCtrl.navigateBack('/router-link-page');
|
||||
}
|
||||
|
||||
navigateRoot() {
|
||||
this.navCtrl.navigateRoot('/router-link-page');
|
||||
}
|
||||
|
||||
counter() {
|
||||
this.changes++;
|
||||
return Math.floor(this.changes / 2);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.onInit++;
|
||||
}
|
||||
|
||||
ionViewWillEnter() {
|
||||
if (this.onInit !== 1) {
|
||||
throw new Error('ngOnInit was not called');
|
||||
}
|
||||
NgZone.assertInAngularZone();
|
||||
this.willEnter++;
|
||||
}
|
||||
ionViewDidEnter() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.didEnter++;
|
||||
}
|
||||
ionViewWillLeave() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.willLeave++;
|
||||
}
|
||||
ionViewDidLeave() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.didLeave++;
|
||||
}
|
||||
}
|
31
angular/test/base/src/app/slides/slides.component.html
Normal file
31
angular/test/base/src/app/slides/slides.component.html
Normal file
@ -0,0 +1,31 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Slides Test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-slides pager="true" (ionSlideDidChange)="checkIndex()">
|
||||
|
||||
<ion-slide *ngFor="let text of slidesData">
|
||||
<h1>{{text}}</h1>
|
||||
</ion-slide>
|
||||
|
||||
</ion-slides>
|
||||
|
||||
<p>
|
||||
index: <span id="slide-index">{{slideIndex}}</span>
|
||||
index2: <span id="slide-index-2">{{slideIndex2}}</span>
|
||||
</p>
|
||||
|
||||
<ion-button id="add-slides" (click)="addSlides()">
|
||||
Add Slides
|
||||
</ion-button>
|
||||
<ion-button id="btn-prev" (click)="prevSlide()">
|
||||
Prev Slide
|
||||
</ion-button>
|
||||
<ion-button id="btn-next" (click)="nextSlide()">
|
||||
Next Slide
|
||||
</ion-button>
|
||||
</ion-content>
|
40
angular/test/base/src/app/slides/slides.component.ts
Normal file
40
angular/test/base/src/app/slides/slides.component.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { AfterViewInit, Component, ViewChild } from '@angular/core';
|
||||
import { IonSlides } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-slides',
|
||||
templateUrl: './slides.component.html',
|
||||
})
|
||||
export class SlidesComponent implements AfterViewInit {
|
||||
@ViewChild(IonSlides, { static: true }) slides: IonSlides;
|
||||
|
||||
slideIndex = 0;
|
||||
slideIndex2 = 0;
|
||||
slidesData = [];
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.slides.ionSlideDidChange.subscribe(async () => {
|
||||
this.slideIndex2 = await this.slides.getActiveIndex();
|
||||
});
|
||||
}
|
||||
|
||||
addSlides() {
|
||||
const start = this.slidesData.length + 1;
|
||||
this.slidesData.push(`Slide ${start}`, `Slide ${start + 1}`, `Slide ${start + 2}`);
|
||||
}
|
||||
|
||||
prevSlide() {
|
||||
this.slides.slidePrev();
|
||||
}
|
||||
|
||||
nextSlide() {
|
||||
this.slides.slideNext();
|
||||
}
|
||||
|
||||
async checkIndex() {
|
||||
this.slideIndex = await this.slides.getActiveIndex();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { TabsTab3Component } from './tabs-tab3/tabs-tab3.component';
|
||||
import { TabsTab3NestedComponent } from './tabs-tab3-nested/tabs-tab3-nested.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: TabsTab3Component
|
||||
},
|
||||
{
|
||||
path: 'nested',
|
||||
component: TabsTab3NestedComponent
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class TabsLazyRoutingModule { }
|
17
angular/test/base/src/app/tabs-lazy/tabs-lazy.module.ts
Normal file
17
angular/test/base/src/app/tabs-lazy/tabs-lazy.module.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { TabsLazyRoutingModule } from './tabs-lazy-routing.module';
|
||||
import { TabsTab3Component } from './tabs-tab3/tabs-tab3.component';
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { TabsTab3NestedComponent } from './tabs-tab3-nested/tabs-tab3-nested.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [TabsTab3Component, TabsTab3NestedComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
IonicModule,
|
||||
TabsLazyRoutingModule
|
||||
]
|
||||
})
|
||||
export class TabsLazyModule { }
|
@ -0,0 +1,15 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab 3 - Page 2</ion-title>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button defaultHref="/tabs/lazy"></ion-back-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
@ -0,0 +1,7 @@
|
||||
import { Component } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs-tab3-nested',
|
||||
templateUrl: './tabs-tab3-nested.component.html',
|
||||
})
|
||||
export class TabsTab3NestedComponent {}
|
@ -0,0 +1,15 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab 3 - Page 1</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<h1>LAZY LOADED TAB</h1>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
<ion-button routerLink="/tabs/lazy/nested" id="goto-tab3-page2">Go to Tab 3 - Page 2</ion-button>
|
||||
|
||||
</p>
|
||||
</ion-content>
|
@ -0,0 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs-tab3',
|
||||
templateUrl: './tabs-tab3.component.html',
|
||||
})
|
||||
export class TabsTab3Component {}
|
@ -0,0 +1,17 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab 1 - Page 2 ({{id}})</ion-title>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Welcome to NESTED PAGE {{id}}</h1>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/contact" id="goto-tab2-page1">Go to Tab 2 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/{{next()}}" id="goto-next">Go to Next</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
@ -0,0 +1,21 @@
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs-tab1-nested',
|
||||
templateUrl: './tabs-tab1-nested.component.html',
|
||||
})
|
||||
export class TabsTab1NestedComponent implements OnInit {
|
||||
id = '';
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.id = this.route.snapshot.paramMap.get('id');
|
||||
}
|
||||
|
||||
next() {
|
||||
return parseInt(this.id, 10) + 1;
|
||||
}
|
||||
}
|
23
angular/test/base/src/app/tabs-tab1/tabs-tab1.component.html
Normal file
23
angular/test/base/src/app/tabs-tab1/tabs-tab1.component.html
Normal file
@ -0,0 +1,23 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>{{title}}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Welcome to Tab1</h1>
|
||||
<ion-segment [(ngModel)]="segment" (ionChange)="segmentChanged($event)">
|
||||
<ion-segment-button value="one">One</ion-segment-button>
|
||||
<ion-segment-button value="two">Two</ion-segment-button>
|
||||
</ion-segment>
|
||||
<p>
|
||||
Segment changed: <span class="segment-changed">{{changed}}</span>
|
||||
</p>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Page 2</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/1" [queryParams]="{search:'hello'}" fragment="fragment"
|
||||
id="goto-nested-page1-with-query-params">Go to Page 2 with Query Params</ion-button>
|
||||
<ion-button routerLink="/tabs/lazy/nested" id="goto-tab3-page2">Go to Tab 3 - Page 2</ion-button>
|
||||
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
24
angular/test/base/src/app/tabs-tab1/tabs-tab1.component.ts
Normal file
24
angular/test/base/src/app/tabs-tab1/tabs-tab1.component.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Component, NgZone } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs-tab1',
|
||||
templateUrl: './tabs-tab1.component.html',
|
||||
})
|
||||
export class TabsTab1Component {
|
||||
title = 'ERROR';
|
||||
segment = 'one';
|
||||
changed = 'false';
|
||||
|
||||
ionViewWillEnter() {
|
||||
NgZone.assertInAngularZone();
|
||||
setTimeout(() => {
|
||||
NgZone.assertInAngularZone();
|
||||
this.title = 'Tab 1 - Page 1';
|
||||
});
|
||||
}
|
||||
|
||||
segmentChanged(ev: any) {
|
||||
console.log('Segment changed', ev);
|
||||
this.changed = 'true';
|
||||
}
|
||||
}
|
21
angular/test/base/src/app/tabs-tab2/tabs-tab2.component.html
Normal file
21
angular/test/base/src/app/tabs-tab2/tabs-tab2.component.html
Normal file
@ -0,0 +1,21 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>{{title}}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Welcome to Tab 2</h1>
|
||||
<ion-segment [(ngModel)]="segment" (ionChange)="segmentChanged($event)">
|
||||
<ion-segment-button value="one">One</ion-segment-button>
|
||||
<ion-segment-button value="two">Two</ion-segment-button>
|
||||
</ion-segment>
|
||||
<p>
|
||||
Segment changed: <span class="segment-changed">{{changed}}</span>
|
||||
</p>
|
||||
<p>
|
||||
<ion-button routerLink="/tabs/account" id="goto-tab1-page1">Go to Tab 1 - Page 1</ion-button>
|
||||
<ion-button routerLink="/tabs/account/nested/1" id="goto-tab1-page2">Go to Tab 1 - Page 2</ion-button>
|
||||
<ion-button routerLink="/nested-outlet/page" id="goto-nested-page1">Go to nested</ion-button>
|
||||
</p>
|
||||
</ion-content>
|
24
angular/test/base/src/app/tabs-tab2/tabs-tab2.component.ts
Normal file
24
angular/test/base/src/app/tabs-tab2/tabs-tab2.component.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { Component, NgZone, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs-tab2',
|
||||
templateUrl: './tabs-tab2.component.html',
|
||||
})
|
||||
export class TabsTab2Component implements OnInit {
|
||||
title = 'ERROR';
|
||||
segment = 'two';
|
||||
changed = 'false';
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
setTimeout(() => {
|
||||
NgZone.assertInAngularZone();
|
||||
this.title = 'Tab 2 - Page 1';
|
||||
});
|
||||
}
|
||||
|
||||
segmentChanged(ev: any) {
|
||||
console.log('Segment changed', ev);
|
||||
this.changed = 'true';
|
||||
}
|
||||
}
|
5
angular/test/base/src/app/tabs/tabs.component.css
Normal file
5
angular/test/base/src/app/tabs/tabs.component.css
Normal file
@ -0,0 +1,5 @@
|
||||
#test {
|
||||
position: absolute;
|
||||
bottom: 100px;
|
||||
left: 0;
|
||||
}
|
46
angular/test/base/src/app/tabs/tabs.component.html
Normal file
46
angular/test/base/src/app/tabs/tabs.component.html
Normal file
@ -0,0 +1,46 @@
|
||||
<ion-tabs (ionTabsDidChange)="tabChanged($event)" (ionTabsWillChange)="tabsWillChange($event)">
|
||||
<ion-tab-bar>
|
||||
<ion-tab-button tab="account">
|
||||
<ion-label>Tab One</ion-label>
|
||||
<ion-icon name="add"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="contact">
|
||||
<ion-label>Tab Two</ion-label>
|
||||
<ion-icon name="logo-ionic"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
<ion-tab-button tab="lazy">
|
||||
<ion-label>Tab Three</ion-label>
|
||||
<ion-icon name="save"></ion-icon>
|
||||
</ion-tab-button>
|
||||
|
||||
</ion-tab-bar>
|
||||
</ion-tabs>
|
||||
<ion-fab horizontal="end" vertical="top">
|
||||
<ion-fab-button id="tabs-state" style="width: 100px;">{{tabsDidChangeCounter}}.{{tabsDidChangeEvent}}</ion-fab-button>
|
||||
</ion-fab>
|
||||
<div id="test">
|
||||
<ul>
|
||||
<li>
|
||||
ionTabsWillChange counter: <span id="ionTabsWillChangeCounter">{{ tabsWillChangeCounter }}</span>
|
||||
</li>
|
||||
<li>
|
||||
ionTabsWillChange event: <span id="ionTabsWillChangeEvent">{{ tabsWillChangeEvent }}</span>
|
||||
</li>
|
||||
<li>
|
||||
ionTabsWillChange selectedTab: <span id="ionTabsWillChangeSelectedTab">{{ tabsWillChangeSelectedTab }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
ionTabsDidChange counter: <span id="ionTabsDidChangeCounter">{{ tabsDidChangeCounter }}</span>
|
||||
</li>
|
||||
<li>
|
||||
ionTabsDidChange event: <span id="ionTabsDidChangeEvent">{{ tabsDidChangeEvent }}</span>
|
||||
</li>
|
||||
<li>
|
||||
ionTabsDidChange selectedTab: <span id="ionTabsDidChangeSelectedTab">{{ tabsDidChangeSelectedTab }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
33
angular/test/base/src/app/tabs/tabs.component.ts
Normal file
33
angular/test/base/src/app/tabs/tabs.component.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { IonTabBar } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-tabs',
|
||||
templateUrl: './tabs.component.html',
|
||||
styleUrls: ['./tabs.component.css']
|
||||
})
|
||||
export class TabsComponent {
|
||||
tabsDidChangeCounter = 0;
|
||||
tabsDidChangeEvent = '';
|
||||
tabsDidChangeSelectedTab = '';
|
||||
|
||||
tabsWillChangeCounter = 0;
|
||||
tabsWillChangeEvent = '';
|
||||
tabsWillChangeSelectedTab = '';
|
||||
|
||||
@ViewChild(IonTabBar) tabBar: IonTabBar;
|
||||
|
||||
tabChanged(ev: { tab: string }) {
|
||||
console.log('ionTabsDidChange', this.tabBar.selectedTab);
|
||||
this.tabsDidChangeCounter++;
|
||||
this.tabsDidChangeEvent = ev.tab;
|
||||
this.tabsDidChangeSelectedTab = this.tabBar.selectedTab;
|
||||
}
|
||||
|
||||
tabsWillChange(ev: { tab: string }) {
|
||||
console.log('ionTabsWillChange', this.tabBar.selectedTab);
|
||||
this.tabsWillChangeCounter++;
|
||||
this.tabsWillChangeEvent = ev.tab;
|
||||
this.tabsWillChangeSelectedTab = this.tabBar.selectedTab;
|
||||
}
|
||||
}
|
27
angular/test/base/src/app/tabs/tabs.module.ts
Executable file
27
angular/test/base/src/app/tabs/tabs.module.ts
Executable file
@ -0,0 +1,27 @@
|
||||
import { IonicModule } from '@ionic/angular';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { TabsPageRoutingModule } from './tabs.router.module';
|
||||
import { TabsComponent } from './tabs.component';
|
||||
import { TabsTab1Component } from '../tabs-tab1/tabs-tab1.component';
|
||||
import { TabsTab2Component } from '../tabs-tab2/tabs-tab2.component';
|
||||
import { TabsTab1NestedComponent } from '../tabs-tab1-nested/tabs-tab1-nested.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicModule,
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
TabsPageRoutingModule
|
||||
],
|
||||
declarations: [
|
||||
TabsComponent,
|
||||
TabsTab1Component,
|
||||
TabsTab2Component,
|
||||
TabsTab1NestedComponent
|
||||
]
|
||||
})
|
||||
export class TabsPageModule {}
|
52
angular/test/base/src/app/tabs/tabs.router.module.ts
Executable file
52
angular/test/base/src/app/tabs/tabs.router.module.ts
Executable file
@ -0,0 +1,52 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { TabsComponent } from './tabs.component';
|
||||
import { TabsTab1NestedComponent } from '../tabs-tab1-nested/tabs-tab1-nested.component';
|
||||
import { TabsTab1Component } from '../tabs-tab1/tabs-tab1.component';
|
||||
import { TabsTab2Component } from '../tabs-tab2/tabs-tab2.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: TabsComponent,
|
||||
children: [
|
||||
{
|
||||
path: 'account',
|
||||
children: [
|
||||
{
|
||||
path: 'nested/:id',
|
||||
component: TabsTab1NestedComponent
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
component: TabsTab1Component
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'contact',
|
||||
children: [
|
||||
{
|
||||
path: 'one',
|
||||
component: TabsTab2Component
|
||||
},
|
||||
{
|
||||
path: '',
|
||||
redirectTo: 'one',
|
||||
pathMatch: 'full'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: 'lazy',
|
||||
loadChildren: () => import('../tabs-lazy/tabs-lazy.module').then(m => m.TabsLazyModule)
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class TabsPageRoutingModule {}
|
2
angular/test/base/src/app/version-test/index.ts
Normal file
2
angular/test/base/src/app/version-test/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './version-test.component';
|
||||
export * from './version-test.module';
|
@ -0,0 +1,16 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule } from "@angular/router";
|
||||
import { VersionTestComponent } from ".";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{
|
||||
path: '',
|
||||
component: VersionTestComponent
|
||||
}
|
||||
])
|
||||
],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class VersionTestRoutingModule { }
|
@ -0,0 +1 @@
|
||||
Version-specific tests
|
@ -0,0 +1,8 @@
|
||||
import { Component } from "@angular/core";
|
||||
|
||||
@Component({
|
||||
selector: 'app-version-test',
|
||||
templateUrl: 'version-test.component.html'
|
||||
})
|
||||
export class VersionTestComponent {
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { NgModule } from "@angular/core";
|
||||
import { IonicModule } from "@ionic/angular";
|
||||
import { VersionTestRoutingModule } from "./version-test-routing.module";
|
||||
import { VersionTestComponent } from "./version-test.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, IonicModule, VersionTestRoutingModule],
|
||||
declarations: [VersionTestComponent],
|
||||
exports: [VersionTestComponent]
|
||||
})
|
||||
export class VersionTestModule { }
|
@ -0,0 +1,20 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
ViewChild() test
|
||||
</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-slides>
|
||||
<ion-slide #slide>
|
||||
<ion-button id="color-button">Hello! it's a button</ion-button>
|
||||
<div #div id="tabs-result"></div>
|
||||
<ion-tabs>
|
||||
</ion-tabs>
|
||||
</ion-slide>
|
||||
<ion-slide>
|
||||
<h1>Second slide</h1>
|
||||
</ion-slide>
|
||||
</ion-slides>
|
||||
</ion-content>
|
23
angular/test/base/src/app/view-child/view-child.component.ts
Normal file
23
angular/test/base/src/app/view-child/view-child.component.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { Component, ViewChild, AfterViewInit, ElementRef } from '@angular/core';
|
||||
import { IonTabs, IonButton, IonSlides, IonSlide } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-view-child',
|
||||
templateUrl: './view-child.component.html'
|
||||
})
|
||||
export class ViewChildComponent implements AfterViewInit {
|
||||
|
||||
@ViewChild(IonSlides, { static: true }) slides: IonSlides;
|
||||
@ViewChild(IonButton, { static: true }) button: IonButton;
|
||||
@ViewChild(IonTabs, { static: true }) tabs: IonTabs;
|
||||
@ViewChild('div', { static: true }) div: ElementRef;
|
||||
@ViewChild('slide', { static: true }) slide: IonSlide;
|
||||
|
||||
ngAfterViewInit() {
|
||||
const loaded = !!(this.slides && this.button && this.tabs && this.div && this.slide);
|
||||
this.button.color = 'danger';
|
||||
if (loaded) {
|
||||
this.div.nativeElement.textContent = 'all found';
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>virtual-scroll page</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<h1>Item {{itemNu}}</h1>
|
||||
<p>ngOnInit: <span id="ngOnInit">{{onInit}}</span></p>
|
||||
<p>ionViewWillEnter: <span id="ionViewWillEnter">{{willEnter}}</span></p>
|
||||
<p>ionViewDidEnter: <span id="ionViewDidEnter">{{didEnter}}</span></p>
|
||||
<p>ionViewWillLeave: <span id="ionViewWillLeave">{{willLeave}}</span></p>
|
||||
<p>ionViewDidLeave: <span id="ionViewDidLeave">{{didLeave}}</span></p>
|
||||
</ion-content>
|
@ -0,0 +1,46 @@
|
||||
import { Component, NgZone, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ViewDidEnter, ViewDidLeave, ViewWillEnter, ViewWillLeave } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-virtual-scroll-detail',
|
||||
templateUrl: './virtual-scroll-detail.component.html',
|
||||
})
|
||||
export class VirtualScrollDetailComponent implements OnInit, ViewWillEnter, ViewDidEnter, ViewWillLeave, ViewDidLeave {
|
||||
|
||||
onInit = 0;
|
||||
willEnter = 0;
|
||||
didEnter = 0;
|
||||
willLeave = 0;
|
||||
didLeave = 0;
|
||||
|
||||
itemNu = 'none';
|
||||
|
||||
constructor(private route: ActivatedRoute) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.itemNu = this.route.snapshot.paramMap.get('itemId');
|
||||
NgZone.assertInAngularZone();
|
||||
this.onInit++;
|
||||
}
|
||||
|
||||
ionViewWillEnter() {
|
||||
if (this.onInit !== 1) {
|
||||
throw new Error('ngOnInit was not called');
|
||||
}
|
||||
NgZone.assertInAngularZone();
|
||||
this.willEnter++;
|
||||
}
|
||||
ionViewDidEnter() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.didEnter++;
|
||||
}
|
||||
ionViewWillLeave() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.willLeave++;
|
||||
}
|
||||
ionViewDidLeave() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.didLeave++;
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
<p>
|
||||
[{{onInit}}] Item {{value}}
|
||||
</p>
|
@ -0,0 +1,17 @@
|
||||
import { Component, OnInit, NgZone, Input } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-virtual-scroll-inner',
|
||||
templateUrl: './virtual-scroll-inner.component.html',
|
||||
})
|
||||
export class VirtualScrollInnerComponent implements OnInit {
|
||||
|
||||
@Input() value: string;
|
||||
onInit = 0;
|
||||
|
||||
ngOnInit() {
|
||||
NgZone.assertInAngularZone();
|
||||
this.onInit++;
|
||||
console.log('created');
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>
|
||||
Virtual Scroll Test
|
||||
</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="addItems()">
|
||||
<ion-icon name="add" slot="icon-only"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content>
|
||||
<ion-virtual-scroll [items]="items" [headerFn]="myHeaderFn" [footerFn]="myFooterFn">
|
||||
<ion-item-divider *virtualHeader="let header">{{ header }}</ion-item-divider>
|
||||
<ion-item-divider *virtualFooter="let footer">-- {{ footer }}</ion-item-divider>
|
||||
<!-- <ion-item *virtualItem="let item" itemHeight="itemHeight">
|
||||
{{item.name}}
|
||||
</ion-item> -->
|
||||
<ion-item *virtualItem="let item" [routerLink]="['/', 'virtual-scroll-detail', item]">
|
||||
<ion-label>
|
||||
<app-virtual-scroll-inner [value]="item.name"></app-virtual-scroll-inner>
|
||||
</ion-label>
|
||||
<ion-icon *ngIf="(item.name % 2) === 0" name="airplane" slot="start"></ion-icon>
|
||||
<ion-toggle slot="end" [(ngModel)]="item.checked"></ion-toggle>
|
||||
</ion-item>
|
||||
</ion-virtual-scroll>
|
||||
</ion-content>
|
@ -0,0 +1,36 @@
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { HeaderFn } from '@ionic/core';
|
||||
import { IonVirtualScroll } from '@ionic/angular';
|
||||
|
||||
@Component({
|
||||
selector: 'app-virtual-scroll',
|
||||
templateUrl: './virtual-scroll.component.html',
|
||||
})
|
||||
export class VirtualScrollComponent {
|
||||
|
||||
@ViewChild(IonVirtualScroll, { static: true }) virtualScroll: IonVirtualScroll;
|
||||
|
||||
items = Array.from({length: 100}, (_, i) => ({ name: `${i}`, checked: true}));
|
||||
|
||||
itemHeight = () => 44;
|
||||
|
||||
myHeaderFn: HeaderFn = (_, index) => {
|
||||
if ((index % 10) === 0) {
|
||||
return `Header ${index}`;
|
||||
}
|
||||
}
|
||||
|
||||
myFooterFn: HeaderFn = (_, index) => {
|
||||
if ((index % 5) === 0) {
|
||||
return `Footer ${index}`;
|
||||
}
|
||||
}
|
||||
|
||||
addItems() {
|
||||
console.log('adding items');
|
||||
this.items.push(
|
||||
{ name: `New Item`, checked: true}
|
||||
);
|
||||
this.virtualScroll.checkEnd();
|
||||
}
|
||||
}
|
0
angular/test/base/src/assets/.gitkeep
Normal file
0
angular/test/base/src/assets/.gitkeep
Normal file
3
angular/test/base/src/environments/environment.prod.ts
Normal file
3
angular/test/base/src/environments/environment.prod.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const environment = {
|
||||
production: true
|
||||
};
|
16
angular/test/base/src/environments/environment.ts
Normal file
16
angular/test/base/src/environments/environment.ts
Normal file
@ -0,0 +1,16 @@
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
export const environment = {
|
||||
production: false
|
||||
};
|
||||
|
||||
/*
|
||||
* For easier debugging in development mode, you can import the following file
|
||||
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||
*
|
||||
* This import should be commented out in production mode because it will have a negative impact
|
||||
* on performance if an error is thrown.
|
||||
*/
|
||||
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
|
BIN
angular/test/base/src/favicon.ico
Normal file
BIN
angular/test/base/src/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
14
angular/test/base/src/index.html
Normal file
14
angular/test/base/src/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>TestApp</title>
|
||||
<base href="/">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
10
angular/test/base/src/main.server.ts
Normal file
10
angular/test/base/src/main.server.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
export { AppServerModule } from './app/app.server.module';
|
||||
export { renderModule, renderModuleFactory } from '@angular/platform-server';
|
15
angular/test/base/src/main.ts
Normal file
15
angular/test/base/src/main.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
|
||||
import { AppModule } from './app/app.module';
|
||||
import { environment } from './environments/environment';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
platformBrowserDynamic()
|
||||
.bootstrapModule(AppModule)
|
||||
.catch(err => console.error(err));
|
||||
});
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user