chore(angular/providers): making progress on angular providers, fix merge issues

* chore(input): remove interface .d.ts file, move to .ts file

* refactor(angular): start working on providers, etc

* chore(angular/dependencies): update deps for angular demo
This commit is contained in:
Dan Bucholtz
2017-11-21 11:58:57 -06:00
committed by GitHub
parent d17dfea4c5
commit f269766068
16 changed files with 1125 additions and 690 deletions

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@
"@angular/platform-browser": "^5.0.0", "@angular/platform-browser": "^5.0.0",
"@angular/platform-browser-dynamic": "^5.0.0", "@angular/platform-browser-dynamic": "^5.0.0",
"@angular/router": "^5.0.0", "@angular/router": "^5.0.0",
"@ionic/core": "latest",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"rxjs": "^5.5.2", "rxjs": "^5.5.2",
"zone.js": "^0.8.14" "zone.js": "^0.8.14"

View File

@ -0,0 +1,24 @@
import { Component } from '@angular/core';
import { AlertController } from '../../../../src/providers/alert-controller';
@Component({
selector: 'app-alert-page',
template: `
<button (click)="clickMe()">Click Me</button>
`
})
export class AlertPageComponent {
constructor(private alertController: AlertController) {
}
clickMe() {
const alert = this.alertController.create({
message: 'Gretting from an ng cli app'
});
alert.present();
}
}

View File

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AlertPageComponent } from './alert-page.component';
const routes: Routes = [
{ path: '', component: AlertPageComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class AlertRoutingModule { }

View File

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AlertPageComponent } from './alert-page.component';
import { AlertRoutingModule } from './alert-routing.module';
@NgModule({
imports: [
CommonModule,
AlertRoutingModule
],
declarations: [AlertPageComponent]
})
export class AlertModule { }

View File

@ -5,7 +5,8 @@ const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' }, { path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'basic-inputs', loadChildren: 'app/basic-inputs-page/basic-inputs-page.module#BasicInputsPageModule' }, { path: 'basic-inputs', loadChildren: 'app/basic-inputs-page/basic-inputs-page.module#BasicInputsPageModule' },
{ path: 'group-inputs', loadChildren: 'app/group-inputs-page/group-inputs-page.module#GroupInputsPageModule' }, { path: 'group-inputs', loadChildren: 'app/group-inputs-page/group-inputs-page.module#GroupInputsPageModule' },
{ path: 'home', loadChildren: 'app/home-page/home-page.module#HomePageModule' } { path: 'home', loadChildren: 'app/home-page/home-page.module#HomePageModule' },
{ path: 'alert', loadChildren: 'app/alert/alert.module#AlertModule' }
]; ];
@NgModule({ @NgModule({

View File

@ -4,9 +4,15 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { IonicAngularModule } from '../../../src/module';
@NgModule({ @NgModule({
declarations: [AppComponent], declarations: [AppComponent],
imports: [AppRoutingModule, BrowserModule], imports: [
AppRoutingModule,
BrowserModule,
IonicAngularModule
],
providers: [], providers: [],
bootstrap: [AppComponent], bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA] schemas: [CUSTOM_ELEMENTS_SCHEMA]

View File

@ -19,135 +19,22 @@
"type": "git", "type": "git",
"url": "https://github.com/ionic-team/ionic.git" "url": "https://github.com/ionic-team/ionic.git"
}, },
"scripts": { "scripts": {},
"build": "stencil build",
"dev": "stencil build --dev --watch",
"test": "gulp validate",
"test:generators": "jasmine-node ./tooling/spec",
"link": "gulp release.prepareReleasePackage && cd dist/ionic-angular && npm link",
"link.stencil": "npm link @stencil/core"
},
"dependencies": { "dependencies": {
"@angular/common": "4.1.3", "@angular/common": "5.0.1",
"@angular/compiler": "4.1.3", "@angular/compiler": "5.0.1",
"@angular/compiler-cli": "4.1.3", "@angular/compiler-cli": "5.0.1",
"@angular/core": "4.1.3", "@angular/core": "5.0.1",
"@angular/forms": "4.1.3", "@angular/forms": "5.0.1",
"@angular/http": "4.1.3", "@angular/http": "5.0.1",
"@angular/platform-browser": "4.1.3", "@angular/platform-browser": "5.0.1",
"@angular/platform-browser-dynamic": "4.1.3", "@angular/platform-browser-dynamic": "5.0.1",
"@ionic/core": "^0.0.1", "@ionic/core": "latest",
"ionicons": "~3.0.0", "ionicons": "~3.0.0",
"rxjs": "5.4.0", "rxjs": "5.5.2",
"zone.js": "0.8.12" "zone.js": "0.8.18"
}, },
"devDependencies": { "devDependencies": {
"@ionic/app-scripts": "1.3.7", "typescript": "~2.4.2"
"@ionic/commit-hooks": "1.0.3", }
"@types/connect": "3.4.30",
"@types/del": "2.2.31",
"@types/fs-extra": "0.0.37",
"@types/glob": "5.0.30",
"@types/gulp": "3.8.32",
"@types/gulp-watch": "4.1.29",
"@types/hammerjs": "2.0.33",
"@types/jasmine": "2.2.34",
"@types/lodash": "4.14.35",
"@types/merge2": "0.3.29",
"@types/mkdirp": "0.3.29",
"@types/node": "^6.0.34",
"@types/protractor": "^4.0.0",
"@types/run-sequence": "0.0.28",
"@types/semver": "5.3.30",
"@types/serve-static": "1.7.31",
"@types/systemjs": "^0.19.33",
"@types/through2": "2.0.29",
"babel-plugin-transform-es2015-modules-systemjs": "6.14.0",
"babel-preset-es2015": "6.16.0",
"canonical-path": "0.0.2",
"connect": "3.5.0",
"conventional-changelog": "1.1.0",
"core-js": "2.4.1",
"cpr": "2.0.0",
"del": "2.2.2",
"dgeni": "^0.4.7",
"dgeni-packages": "^0.16.10",
"dotenv": "4.0.0",
"event-stream": "3.3.4",
"file-loader": "0.9.0",
"fs-extra": "^2.0.0",
"github": "0.2.4",
"glob": "7.0.6",
"gulp": "3.9.1",
"gulp-autoprefixer": "3.1.1",
"gulp-babel": "6.1.2",
"gulp-cached": "1.1.0",
"gulp-clean-css": "2.0.12",
"gulp-concat": "2.6.0",
"gulp-connect": "5.0.0",
"gulp-conventional-changelog": "1.1.0",
"gulp-git": "1.11.3",
"gulp-if": "2.0.1",
"gulp-open": "2.0.0",
"gulp-remember": "0.3.1",
"gulp-rename": "1.2.2",
"gulp-sass": "2.3.2",
"gulp-scss-lint": "0.4.0",
"gulp-shell": "0.5.2",
"gulp-strip-debug": "1.1.0",
"gulp-tslint": "6.1.1",
"gulp-typescript": "2.13.6",
"gulp-uglify": "2.0.0",
"gulp-util": "3.0.7",
"gulp-watch": "4.3.9",
"html-entities": "1.2.0",
"inquirer": "3.0.1",
"ionic-cz-conventional-changelog": "1.0.0",
"ionic-native": "^2.2.6",
"jasmine-core": "2.5.2",
"jasmine-node": "1.14.5",
"karma": "1.3.0",
"karma-chrome-launcher": "2.0.0",
"karma-coverage": "1.1.1",
"karma-jasmine": "1.0.2",
"karma-sourcemap-loader": "0.3.7",
"karma-spec-reporter": "0.0.26",
"merge2": "1.0.2",
"mkdirp": "0.5.1",
"node-html-encoder": "0.0.2",
"p-all": "^1.0.0",
"remap-istanbul": "0.6.4",
"request": "2.75.0",
"resolve-bin": "0.4.0",
"rollup": "0.36.0",
"rollup-plugin-commonjs": "8.0.2",
"rollup-plugin-multi-entry": "2.0.1",
"rollup-plugin-node-resolve": "3.0.0",
"rollup-plugin-uglify": "1.0.1",
"run-sequence": "1.2.2",
"s3": "4.4.0",
"sassdoc": "2.2.1",
"semver": "5.3.0",
"serve-static": "1.11.1",
"strip-function": "0.0.3",
"sw-toolbox": "3.4.0",
"systemjs": "0.19.38",
"through2": "2.0.1",
"ts-node": "1.3.0",
"tslint": "3.15.1",
"tslint-ionic-rules": "0.0.8",
"typescript": "~2.3.3",
"vinyl": "1.2.0",
"webpack": "^2.1.0-beta.27",
"yargs": "5.0.0"
},
"config": {
"commitizen": {
"path": "node_modules/ionic-cz-conventional-changelog"
},
"ionic_copy": "./scripts/demos/copy.config.js"
},
"pre-push#master": [
"test"
]
} }

View File

@ -0,0 +1,109 @@
import {
AfterViewInit,
ChangeDetectorRef,
Component,
ComponentFactoryResolver,
Directive,
ElementRef,
Injector,
InjectionToken,
NgZone,
OnInit,
ReflectiveInjector,
ViewContainerRef,
ViewChild
} from '@angular/core';
import { NavController, ViewController } from '@ionic/core';
import { App } from '../providers/app';
import { NavController as InjectableNavController } from '../providers/nav-controller';
@Component({
selector: 'ion-nav',
template: `
<div #viewport class="ng-nav-viewport"></div>
`
})
export class IonNavDelegate {
@ViewChild('viewport', { read: ViewContainerRef}) viewport: ViewContainerRef;
constructor(private crf: ComponentFactoryResolver, private changeDetection: ChangeDetectorRef, private zone: NgZone, private injector: Injector) {
}
ngOnInit() {
const controllerElement = document.querySelector('ion-nav-controller') as any;
controllerElement.delegate = this;
}
attachViewToDom(nav: NavController, enteringView: ViewController): Promise<any> {
return new Promise((resolve, reject) => {
this.zone.run(() => {
const componentProviders = ReflectiveInjector.resolve([
{
provide: NavControllerToken, useValue: nav.element,
},
{
provide: NavController, useFactory: provideNavControllerInjectable, deps: [NavControllerToken]
},
{
provide: AppToken, useValue: null,
},
{
provide: App, useFactory: provideAppInjectable, deps: [AppToken]
}
]);
const componentFactory = this.crf.resolveComponentFactory(enteringView.component);
const childInjector = ReflectiveInjector.fromResolvedProviders(componentProviders, this.viewport.parentInjector);
const componentRef = componentFactory.create(childInjector, []);
this.viewport.insert(componentRef.hostView, this.viewport.length);
this.changeDetection.detectChanges();
(enteringView as any).componentFactory = componentFactory;
(enteringView as any).childInjector = childInjector;
(enteringView as any).componentRef = componentRef;
enteringView.instance = componentRef.instance;
(enteringView as any).angularHostElement = componentRef.location.nativeElement;
enteringView.element = componentRef.location.nativeElement.querySelector('ion-page');
resolve();
});
});
}
removeViewFromDom(nav: NavController, viewController: ViewController) {
return new Promise((resolve, reject) => {
this.zone.run(() => {
(viewController as any).componentRef.destroy();
// (nav.element as HTMLElement).removeChild(viewController.angularHostElement);
(viewController as any).componentFactory = null;
(viewController as any).childInjector = null;
(viewController as any).componentRef = null;
viewController.instance = null;
(viewController as any).angularHostElement = null;
viewController.element = null;
resolve();
});
})
}
}
export const NavControllerToken = new InjectionToken<any>('NavControllerToken');
export const ViewControllerToken = new InjectionToken<any>('ViewControllerToken');
export const AppToken = new InjectionToken<any>('AppToken');
export function provideNavControllerInjectable(element: any) {
return new InjectableNavController(element);
}
export function provideAppInjectable() {
const ionAppElement = document.querySelector('ion-app');
return new App(ionAppElement);
}

View File

@ -0,0 +1,23 @@
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { IonNavDelegate } from './directives/ion-nav';
import { AlertController } from './providers/alert-controller';
@NgModule({
declarations: [
IonNavDelegate
],
exports: [
IonNavDelegate
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
],
providers: [
AlertController
]
})
export class IonicAngularModule {
}

View File

@ -0,0 +1,57 @@
import { AlertOptions } from '@ionic/core';
import { ensureElementInBody, hydrateElement } from '../util/util';
let alertId = 0;
export class AlertController {
create(opts?: AlertOptions): AlertProxy {
return getAlertProxy(opts);
}
}
export function getAlertProxy(opts: AlertOptions){
return {
id: alertId++,
state: PRESENTING,
opts: opts,
present: function() { return present(this)},
dismiss: function() { return dismiss(this)}
}
}
export function present(alertProxy: AlertProxyInternal): Promise<void> {
return loadOverlay(alertProxy.opts).then((alertElement: HTMLIonAlertElement) => {
if (alertProxy.state === PRESENTING) {
return alertElement.present();
}
});
}
export function dismiss(alertProxy: AlertProxyInternal): Promise<void> {
return loadOverlay(alertProxy.opts).then((alertElement: HTMLIonAlertElement) => {
if (alertProxy.state === DISMISSING) {
return alertElement.dismiss();
}
});
}
export function loadOverlay(opts: AlertOptions) {
const element = ensureElementInBody('ion-alert-controller') as HTMLIonAlertControllerElement;
return hydrateElement(element).then(() => {
return element.create(opts);
});
}
export interface AlertProxy {
present(): Promise<void>
dismiss(): Promise<void>
}
export interface AlertProxyInternal extends AlertProxy {
id: number;
opts: AlertOptions;
state: number;
}
export const PRESENTING = 1;
export const DISMISSING = 2;

View File

@ -0,0 +1,40 @@
import { NavContainer } from '@ionic/core';
import { hydrateElement } from '../util/util';
export class App {
constructor(private element: HTMLIonAppElement) {
}
setTitle(title: string) {
document.title = title;
}
isScrolling(): boolean {
if (this.element.isScrolling) {
return this.element.isScrolling();
}
return false;
}
getRootNavs(): NavContainer[] {
if (this.element.getRootNavs) {
return this.element.getRootNavs();
}
return [];
}
getActiveNavs(rootNavId?: number): NavContainer[] {
if (this.element.getActiveNavs) {
return this.element.getActiveNavs(rootNavId);
}
return [];
}
getNavByIdOrName(nameOrId: number | string): NavContainer {
if (this.element.getNavByIdOrName) {
return this.element.getNavByIdOrName(nameOrId);
}
return null;
}
}

View File

@ -0,0 +1,102 @@
import { NavOptions, PublicNavController, ViewController } from '@ionic/core';
import { hydrateElement } from '../util/util';
export class NavController implements PublicNavController {
constructor(public element: HTMLIonNavElement) {
}
push(component: any, data?: any, opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.push(component, data, opts);
});
}
pop(opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.pop(opts);
});
}
setRoot(component: any, data?: any, opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.setRoot(component, data, opts);
});
}
insert(insertIndex: number, page: any, params?: any, opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.insert(insertIndex, page, params, opts);
});
}
insertPages(insertIndex: number, insertPages: any[], opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.insertPages(insertIndex, insertPages, opts);
});
}
popToRoot(opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.popToRoot(opts);
});
}
popTo(indexOrViewCtrl: any, opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.popTo(indexOrViewCtrl, opts);
});
}
removeIndex(startIndex: number, removeCount?: number, opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.removeIndex(startIndex, removeCount, opts);
});
}
removeView(viewController: ViewController, opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.removeView(viewController, opts);
});
}
setPages(componentDataPairs: any[], opts?: NavOptions): Promise<any> {
return hydrateElement(this.element).then((navElement: HTMLIonNavElement) => {
return navElement.setPages(componentDataPairs, opts);
});
}
getActive(): ViewController {
if (this.element.getActive) {
return this.element.getActive();
}
return null;
}
getPrevious(view?: ViewController): ViewController {
if (this.element.getPrevious) {
return this.element.getPrevious(view);
}
return null;
}
canGoBack(nav: PublicNavController): boolean {
if (this.element.canGoBack) {
return this.element.canGoBack(nav as any);
}
return false;
}
canSwipeBack(): boolean {
if (this.element.canSwipeBack) {
return this.element.canSwipeBack();
}
return false;
}
getFirstView(): ViewController {
if (this.element.getFirstView) {
return this.element.getFirstView();
}
return null;
}
}

View File

@ -0,0 +1,17 @@
export function hydrateElement(element: any) {
return element.componentOnReady();
}
export function getElement(elementName: string) {
return document.querySelector(elementName);
}
export function ensureElementInBody(elementName: string) {
let element = getElement(elementName);
if (!element) {
element = document.createElement(elementName);
document.body.appendChild(element);
}
return element;
}

View File

@ -6,28 +6,17 @@
"emitDecoratorMetadata": true, "emitDecoratorMetadata": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"lib": ["dom", "es2015"], "lib": ["dom", "es2015"],
"module": "commonjs", "module": "es2015",
"moduleResolution": "node", "moduleResolution": "node",
"noImplicitAny": true, "noImplicitAny": true,
"removeComments": false, "removeComments": false,
"sourceMap": true, "sourceMap": true,
"target": "es2015", "target": "es2015"
"typeRoots": [
"./node_modules/@types"
],
"types": ["jasmine", "systemjs"]
}, },
"include": [ "include": [
"src/**/*.ts", "src/**/*.ts",
"demos/src/**/*.ts" "demos/src/**/*.ts"
], ],
"compileOnSave": false, "compileOnSave": false,
"buildOnSave": false, "buildOnSave": false
"atom": {
"rewriteTsconfig": false
},
"angularCompilerOptions": {
"annotationsAs": "static fields",
"annotateForClosureCompiler": true
}
} }