mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 01:52:19 +08:00
refactor(angular): enable TS strict
This commit is contained in:
@ -21,11 +21,12 @@ export class StackController {
|
|||||||
ref: enteringRef,
|
ref: enteringRef,
|
||||||
element: (enteringRef && enteringRef.location && enteringRef.location.nativeElement) as HTMLElement,
|
element: (enteringRef && enteringRef.location && enteringRef.location.nativeElement) as HTMLElement,
|
||||||
url: this.getUrl(route),
|
url: this.getUrl(route),
|
||||||
|
fullpath: document.location.pathname,
|
||||||
deactivatedId: -1
|
deactivatedId: -1
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getExistingView(activatedRoute: ActivatedRoute): RouteView|null {
|
getExistingView(activatedRoute: ActivatedRoute): RouteView | undefined {
|
||||||
const activatedUrlKey = this.getUrl(activatedRoute);
|
const activatedUrlKey = this.getUrl(activatedRoute);
|
||||||
return this.views.find(vw => vw.url === activatedUrlKey);
|
return this.views.find(vw => vw.url === activatedUrlKey);
|
||||||
}
|
}
|
||||||
@ -74,24 +75,28 @@ export class StackController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private cleanup() {
|
private cleanup() {
|
||||||
|
const views = this.views;
|
||||||
this.viewsSnapshot
|
this.viewsSnapshot
|
||||||
.filter(view => !this.views.includes(view))
|
.filter(view => !views.includes(view))
|
||||||
.forEach(view => destroyView(view));
|
.forEach(view => destroyView(view));
|
||||||
|
|
||||||
for (const {element} of this.views) {
|
for (let i = 0; i < views.length - 1; i++) {
|
||||||
|
const element = views[i].element;
|
||||||
element.setAttribute('aria-hidden', 'true');
|
element.setAttribute('aria-hidden', 'true');
|
||||||
element.classList.add('ion-page-hidden');
|
element.classList.add('ion-page-hidden');
|
||||||
}
|
}
|
||||||
this.viewsSnapshot = this.views.slice();
|
|
||||||
|
this.viewsSnapshot = views.slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
getActive(): RouteView | null {
|
getActive(): RouteView | undefined {
|
||||||
return this.views.length > 0 ? this.views[this.views.length - 1] : null;
|
const views = this.views;
|
||||||
|
return views.length > 0 ? views[views.length - 1] : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async transition(
|
private async transition(
|
||||||
enteringView: RouteView,
|
enteringView: RouteView | undefined,
|
||||||
leavingView: RouteView,
|
leavingView: RouteView | undefined,
|
||||||
direction: number,
|
direction: number,
|
||||||
animated: boolean,
|
animated: boolean,
|
||||||
showGoBack: boolean
|
showGoBack: boolean
|
||||||
@ -141,6 +146,7 @@ export function getLastDeactivatedRef(views: RouteView[]) {
|
|||||||
|
|
||||||
export interface RouteView {
|
export interface RouteView {
|
||||||
url: string;
|
url: string;
|
||||||
|
fullpath: string;
|
||||||
element: HTMLElement;
|
element: HTMLElement;
|
||||||
ref: ComponentRef<any>;
|
ref: ComponentRef<any>;
|
||||||
deactivatedId: number;
|
deactivatedId: number;
|
||||||
|
@ -41,18 +41,18 @@ export class VirtualScroll {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private nodeRender(el: HTMLElement|null, cell: any, index?: number) {
|
private nodeRender(el: HTMLElement|null, cell: any, index: number) {
|
||||||
if (!el) {
|
if (!el) {
|
||||||
const node = this.itmTmp.viewContainer.createEmbeddedView(
|
const node = this.itmTmp.viewContainer.createEmbeddedView(
|
||||||
this.getComponent(cell.type),
|
this.getComponent(cell.type),
|
||||||
new VirtualContext(null, null, null),
|
{ $implicit: null, index },
|
||||||
index
|
index
|
||||||
);
|
);
|
||||||
el = getElement(node);
|
el = getElement(node);
|
||||||
(el as any)['$ionView'] = node;
|
(el as any)['$ionView'] = node;
|
||||||
}
|
}
|
||||||
const node = (el as any)['$ionView'];
|
const node = (el as any)['$ionView'];
|
||||||
const ctx = node.context;
|
const ctx = node.context as VirtualContext;
|
||||||
ctx.$implicit = cell.value;
|
ctx.$implicit = cell.value;
|
||||||
ctx.index = cell.index;
|
ctx.index = cell.index;
|
||||||
node.detectChanges();
|
node.detectChanges();
|
||||||
@ -65,11 +65,11 @@ export class VirtualScroll {
|
|||||||
case 1: return this.hdrTmp.templateRef;
|
case 1: return this.hdrTmp.templateRef;
|
||||||
case 2: return this.ftrTmp.templateRef;
|
case 2: return this.ftrTmp.templateRef;
|
||||||
}
|
}
|
||||||
return null;
|
throw new Error('template for virtual item was not provided');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement {
|
function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement | null {
|
||||||
const rootNodes = view.rootNodes;
|
const rootNodes = view.rootNodes;
|
||||||
for (let i = 0; i < rootNodes.length; i++) {
|
for (let i = 0; i < rootNodes.length; i++) {
|
||||||
if (rootNodes[i].nodeType === 1) {
|
if (rootNodes[i].nodeType === 1) {
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
|
|
||||||
export class VirtualContext {
|
export interface VirtualContext {
|
||||||
|
$implicit: any;
|
||||||
constructor(public $implicit: any, public index: number, public count: number) { }
|
index: number;
|
||||||
|
|
||||||
get first(): boolean { return this.index === 0; }
|
|
||||||
|
|
||||||
get last(): boolean { return this.index === this.count - 1; }
|
|
||||||
|
|
||||||
get even(): boolean { return this.index % 2 === 0; }
|
|
||||||
|
|
||||||
get odd(): boolean { return !this.even; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
|||||||
constructor(
|
constructor(
|
||||||
private resolver: ComponentFactoryResolver,
|
private resolver: ComponentFactoryResolver,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
private location: ViewContainerRef,
|
private location: ViewContainerRef | undefined,
|
||||||
private appRef: ApplicationRef,
|
private appRef: ApplicationRef,
|
||||||
private zone: NgZone,
|
private zone: NgZone,
|
||||||
) {}
|
) {}
|
||||||
@ -65,7 +65,7 @@ export function attachView(
|
|||||||
location: ViewContainerRef | undefined,
|
location: ViewContainerRef | undefined,
|
||||||
appRef: ApplicationRef,
|
appRef: ApplicationRef,
|
||||||
elRefMap: WeakMap<HTMLElement, any>,
|
elRefMap: WeakMap<HTMLElement, any>,
|
||||||
container: any, component: any, params: any, cssClasses: string[]
|
container: any, component: any, params: any, cssClasses: string[] | undefined
|
||||||
) {
|
) {
|
||||||
const factory = resolver.resolveComponentFactory(component);
|
const factory = resolver.resolveComponentFactory(component);
|
||||||
const childInjector = Injector.create(getProviders(params), injector);
|
const childInjector = Injector.create(getProviders(params), injector);
|
||||||
@ -78,9 +78,11 @@ export function attachView(
|
|||||||
if (params) {
|
if (params) {
|
||||||
Object.assign(instance, params);
|
Object.assign(instance, params);
|
||||||
}
|
}
|
||||||
|
if (cssClasses) {
|
||||||
for (const clazz of cssClasses) {
|
for (const clazz of cssClasses) {
|
||||||
hostElement.classList.add(clazz);
|
hostElement.classList.add(clazz);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bindLifecycleEvents(instance, hostElement);
|
bindLifecycleEvents(instance, hostElement);
|
||||||
container.appendChild(hostElement);
|
container.appendChild(hostElement);
|
||||||
|
|
||||||
@ -103,8 +105,8 @@ const LIFECYCLES = [
|
|||||||
|
|
||||||
export function bindLifecycleEvents(instance: any, element: HTMLElement) {
|
export function bindLifecycleEvents(instance: any, element: HTMLElement) {
|
||||||
LIFECYCLES.forEach(eventName => {
|
LIFECYCLES.forEach(eventName => {
|
||||||
element.addEventListener(eventName, (ev: CustomEvent) => {
|
element.addEventListener(eventName, (ev: any) => {
|
||||||
if (typeof instance[eventName] === 'function') {
|
if (typeof instance[eventName] === 'function' && ev.detail) {
|
||||||
instance[eventName](ev.detail);
|
instance[eventName](ev.detail);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -18,7 +18,7 @@ export class Config {
|
|||||||
if (c) {
|
if (c) {
|
||||||
return c.getBoolean(key, fallback);
|
return c.getBoolean(key, fallback);
|
||||||
}
|
}
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
getNumber(key: string, fallback?: number): number {
|
getNumber(key: string, fallback?: number): number {
|
||||||
@ -26,7 +26,7 @@ export class Config {
|
|||||||
if (c) {
|
if (c) {
|
||||||
return c.getNumber(key, fallback);
|
return c.getNumber(key, fallback);
|
||||||
}
|
}
|
||||||
return null;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
set(key: string, value?: any) {
|
set(key: string, value?: any) {
|
||||||
@ -39,7 +39,7 @@ export class Config {
|
|||||||
|
|
||||||
export const ConfigToken = new InjectionToken<any>('USERCONFIG');
|
export const ConfigToken = new InjectionToken<any>('USERCONFIG');
|
||||||
|
|
||||||
function getConfig(): CoreConfig {
|
function getConfig(): CoreConfig | null {
|
||||||
const win: IonicWindow = window as any;
|
const win: IonicWindow = window as any;
|
||||||
if (typeof win !== 'undefined') {
|
if (typeof win !== 'undefined') {
|
||||||
const Ionic = win.Ionic;
|
const Ionic = win.Ionic;
|
||||||
|
@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Events {
|
export class Events {
|
||||||
private c: {[topic: string]: Function[]} = [] as any;
|
private c = new Map<string, Function[]>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
|
* Subscribe to an event topic. Events that get posted to that topic will trigger the provided handler.
|
||||||
@ -12,12 +12,11 @@ export class Events {
|
|||||||
* @param {function} handler the event handler
|
* @param {function} handler the event handler
|
||||||
*/
|
*/
|
||||||
subscribe(topic: string, ...handlers: Function[]) {
|
subscribe(topic: string, ...handlers: Function[]) {
|
||||||
if (!this.c[topic]) {
|
let topics = this.c.get(topic);
|
||||||
this.c[topic] = [];
|
if (!topics) {
|
||||||
|
topics = [];
|
||||||
}
|
}
|
||||||
handlers.forEach((handler) => {
|
topics.push(...handlers);
|
||||||
this.c[topic].push(handler);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,34 +27,27 @@ export class Events {
|
|||||||
*
|
*
|
||||||
* @return true if a handler was removed
|
* @return true if a handler was removed
|
||||||
*/
|
*/
|
||||||
unsubscribe(topic: string, handler: Function = null) {
|
unsubscribe(topic: string, handler?: Function): boolean {
|
||||||
const t = this.c[topic];
|
if (!handler) {
|
||||||
if (!t) {
|
return this.c.delete(topic);
|
||||||
// Wasn't found, wasn't removed
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!handler) {
|
const topics = this.c.get(topic);
|
||||||
// Remove all handlers for this topic
|
if (!topics) {
|
||||||
delete this.c[topic];
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to find and remove a specific handler
|
// We need to find and remove a specific handler
|
||||||
const i = t.indexOf(handler);
|
const index = topics.indexOf(handler);
|
||||||
|
|
||||||
if (i < 0) {
|
if (index < 0) {
|
||||||
// Wasn't found, wasn't removed
|
// Wasn't found, wasn't removed
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
topics.splice(index, 1);
|
||||||
t.splice(i, 1);
|
if (topics.length === 0) {
|
||||||
|
this.c.delete(topic);
|
||||||
// If the channel is empty now, remove it from the channel map
|
|
||||||
if (!t.length) {
|
|
||||||
delete this.c[topic];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,17 +57,12 @@ export class Events {
|
|||||||
* @param {string} topic the topic to publish to
|
* @param {string} topic the topic to publish to
|
||||||
* @param {any} eventData the data to send as the event
|
* @param {any} eventData the data to send as the event
|
||||||
*/
|
*/
|
||||||
publish(topic: string, ...args: any[]) {
|
publish(topic: string, ...args: any[]): any[] | null {
|
||||||
const t = this.c[topic];
|
const topics = this.c.get(topic);
|
||||||
if (!t) {
|
if (!topics) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
return topics.map((handler => handler(...args)));
|
||||||
const responses: any[] = [];
|
|
||||||
t.forEach((handler: any) => {
|
|
||||||
responses.push(handler(...args));
|
|
||||||
});
|
|
||||||
return responses;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ export class ModalController extends OverlayBaseController<ModalOptions, HTMLIon
|
|||||||
super('ion-modal-controller');
|
super('ion-modal-controller');
|
||||||
}
|
}
|
||||||
|
|
||||||
create(opts?: ModalOptions): Promise<HTMLIonModalElement> {
|
create(opts: ModalOptions): Promise<HTMLIonModalElement> {
|
||||||
return super.create({
|
return super.create({
|
||||||
...opts,
|
...opts,
|
||||||
delegate: this.angularDelegate.create(this.resolver, this.injector)
|
delegate: this.angularDelegate.create(this.resolver, this.injector)
|
||||||
|
@ -21,17 +21,17 @@ export class NavController {
|
|||||||
|
|
||||||
goForward(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
|
goForward(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
|
||||||
this.setIntent(NavIntent.Forward, animated);
|
this.setIntent(NavIntent.Forward, animated);
|
||||||
return this.router.navigateByUrl(url, extras);
|
return this.router!.navigateByUrl(url, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
goBack(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
|
goBack(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
|
||||||
this.setIntent(NavIntent.Back, animated);
|
this.setIntent(NavIntent.Back, animated);
|
||||||
return this.router.navigateByUrl(url, extras);
|
return this.router!.navigateByUrl(url, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
goRoot(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
|
goRoot(url: string | UrlTree, animated?: boolean, extras?: NavigationExtras) {
|
||||||
this.setIntent(NavIntent.Root, animated);
|
this.setIntent(NavIntent.Root, animated);
|
||||||
return this.router.navigateByUrl(url, extras);
|
return this.router!.navigateByUrl(url, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIntent(intent: NavIntent, animated?: boolean) {
|
setIntent(intent: NavIntent, animated?: boolean) {
|
||||||
|
@ -49,7 +49,7 @@ export class Platform {
|
|||||||
readyResolve('cordova');
|
readyResolve('cordova');
|
||||||
}, {once: true});
|
}, {once: true});
|
||||||
} else {
|
} else {
|
||||||
readyResolve('dom');
|
readyResolve!('dom');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ export class Platform {
|
|||||||
/**
|
/**
|
||||||
* Get the query string parameter
|
* Get the query string parameter
|
||||||
*/
|
*/
|
||||||
getQueryParam(key: string): string {
|
getQueryParam(key: string): string | null {
|
||||||
return readQueryParam(window.location.href, key);
|
return readQueryParam(window.location.href, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ export class PopoverController extends OverlayBaseController<PopoverOptions, HTM
|
|||||||
super('ion-popover-controller');
|
super('ion-popover-controller');
|
||||||
}
|
}
|
||||||
|
|
||||||
create(opts?: PopoverOptions): Promise<HTMLIonPopoverElement> {
|
create(opts: PopoverOptions): Promise<HTMLIonPopoverElement> {
|
||||||
return super.create({
|
return super.create({
|
||||||
...opts,
|
...opts,
|
||||||
delegate: this.angularDelegate.create(this.resolver, this.injector)
|
delegate: this.angularDelegate.create(this.resolver, this.injector)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"alwaysStrict": true,
|
"alwaysStrict": true,
|
||||||
"strict": false,
|
"strict": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"allowUnreachableCode": false,
|
"allowUnreachableCode": false,
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
|
Reference in New Issue
Block a user