mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 03:00:58 +08:00
fix(angular): change detection
This commit is contained in:
@ -1,7 +1,7 @@
|
|||||||
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
|
import { Directive, ElementRef, HostListener, Input, Optional } from '@angular/core';
|
||||||
import { IonRouterOutlet } from './ion-router-outlet';
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { NavController } from '../..';
|
import { NavController } from '../../providers/nav-controller';
|
||||||
|
import { IonRouterOutlet } from './ion-router-outlet';
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: 'ion-back-button'
|
selector: 'ion-back-button'
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import { Directive as NgDirective, ElementRef, EventEmitter as NgEventEmitter, Input as NgInput, Output as NgOutput } from '@angular/core';
|
import { Directive as NgDirective, ElementRef, EventEmitter as NgEventEmitter, Input as NgInput, Output as NgOutput } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
export function method(ref: ElementRef, methodName: string, ...args: any[]) {
|
export function method(ref: ElementRef, methodName: string, args: any[]) {
|
||||||
return ref.nativeElement.componentOnReady()
|
return ref.nativeElement.componentOnReady()
|
||||||
.then((el: any) => el[methodName].apply(el, args));
|
.then((el: any) => el[methodName].apply(el, args));
|
||||||
}
|
}
|
||||||
@ -907,8 +907,6 @@ export class Menu {
|
|||||||
@NgInput() maxEdgeStart: number;
|
@NgInput() maxEdgeStart: number;
|
||||||
@NgOutput() ionOpen: NgEventEmitter<any>;
|
@NgOutput() ionOpen: NgEventEmitter<any>;
|
||||||
@NgOutput() ionClose: NgEventEmitter<any>;
|
@NgOutput() ionClose: NgEventEmitter<any>;
|
||||||
@NgOutput() ionMenuDidLoad: NgEventEmitter<any>;
|
|
||||||
@NgOutput() ionMenuDidUnload: NgEventEmitter<any>;
|
|
||||||
@NgOutput() ionMenuChange: NgEventEmitter<any>;
|
@NgOutput() ionMenuChange: NgEventEmitter<any>;
|
||||||
isOpen(...__args: any[]): Promise<any> {
|
isOpen(...__args: any[]): Promise<any> {
|
||||||
return method(this.r, isOpen, __args);
|
return method(this.r, isOpen, __args);
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
import {
|
import { ApplicationRef, ComponentFactoryResolver, Injectable, Injector, NgZone } from '@angular/core';
|
||||||
ApplicationRef,
|
|
||||||
ComponentFactoryResolver,
|
|
||||||
Injectable,
|
|
||||||
Injector,
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import { FrameworkDelegate, ViewLifecycle } from '@ionic/core';
|
import { FrameworkDelegate, ViewLifecycle } from '@ionic/core';
|
||||||
|
|
||||||
|
|
||||||
@ -12,11 +6,12 @@ import { FrameworkDelegate, ViewLifecycle } from '@ionic/core';
|
|||||||
export class AngularDelegate {
|
export class AngularDelegate {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private appRef: ApplicationRef
|
private appRef: ApplicationRef,
|
||||||
|
private zone: NgZone
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
create(cfr: ComponentFactoryResolver, injector: Injector) {
|
create(cfr: ComponentFactoryResolver, injector: Injector) {
|
||||||
return new AngularFrameworkDelegate(cfr, injector, this.appRef);
|
return new AngularFrameworkDelegate(cfr, injector, this.appRef, this.zone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,40 +23,61 @@ export class AngularFrameworkDelegate implements FrameworkDelegate {
|
|||||||
constructor(
|
constructor(
|
||||||
private cfr: ComponentFactoryResolver,
|
private cfr: ComponentFactoryResolver,
|
||||||
private injector: Injector,
|
private injector: Injector,
|
||||||
private appRef: ApplicationRef
|
private appRef: ApplicationRef,
|
||||||
|
private zone: NgZone,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
attachViewToDom(container: any, component: any, data?: any, cssClasses?: string[]): Promise<any> {
|
attachViewToDom(container: any, component: any, params?: any, cssClasses?: string[]): Promise<any> {
|
||||||
|
return new Promise(resolve => {
|
||||||
const componentFactory = this.cfr.resolveComponentFactory(component);
|
this.zone.run(() => {
|
||||||
const hostElement = document.createElement(componentFactory.selector);
|
const el = attachView(
|
||||||
if (data) {
|
this.cfr, this.injector, this.appRef, this.elRefMap,
|
||||||
Object.assign(hostElement, data);
|
container, component, params, cssClasses
|
||||||
}
|
);
|
||||||
|
resolve(el);
|
||||||
const childInjector = Injector.create([], this.injector);
|
});
|
||||||
const componentRef = componentFactory.create(childInjector, [], hostElement);
|
});
|
||||||
for (const clazz of cssClasses) {
|
|
||||||
hostElement.classList.add(clazz);
|
|
||||||
}
|
|
||||||
bindLifecycleEvents(componentRef.instance, hostElement);
|
|
||||||
container.appendChild(hostElement);
|
|
||||||
|
|
||||||
this.appRef.attachView(componentRef.hostView);
|
|
||||||
this.elRefMap.set(hostElement, componentRef);
|
|
||||||
return Promise.resolve(hostElement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeViewFromDom(_container: any, component: any): Promise<void> {
|
removeViewFromDom(_container: any, component: any): Promise<void> {
|
||||||
const componentRef = this.elRefMap.get(component);
|
return new Promise(resolve => {
|
||||||
if (componentRef) {
|
this.zone.run(() => {
|
||||||
componentRef.destroy();
|
const componentRef = this.elRefMap.get(component);
|
||||||
this.elRefMap.delete(component);
|
if (componentRef) {
|
||||||
}
|
componentRef.destroy();
|
||||||
return Promise.resolve();
|
this.elRefMap.delete(component);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function attachView(
|
||||||
|
cfr: ComponentFactoryResolver,
|
||||||
|
injector: Injector,
|
||||||
|
appRef: ApplicationRef,
|
||||||
|
elRefMap: WeakMap<HTMLElement, any>,
|
||||||
|
container: any, component: any, data?: any, cssClasses?: string[]) {
|
||||||
|
const componentFactory = cfr.resolveComponentFactory(component);
|
||||||
|
const hostElement = document.createElement(componentFactory.selector);
|
||||||
|
if (data) {
|
||||||
|
Object.assign(hostElement, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const childInjector = Injector.create([], injector);
|
||||||
|
const componentRef = componentFactory.create(childInjector, [], hostElement);
|
||||||
|
for (const clazz of cssClasses) {
|
||||||
|
hostElement.classList.add(clazz);
|
||||||
|
}
|
||||||
|
bindLifecycleEvents(componentRef.instance, hostElement);
|
||||||
|
container.appendChild(hostElement);
|
||||||
|
|
||||||
|
appRef.attachView(componentRef.hostView);
|
||||||
|
elRefMap.set(hostElement, componentRef);
|
||||||
|
return hostElement;
|
||||||
|
}
|
||||||
|
|
||||||
const LIFECYCLES = [
|
const LIFECYCLES = [
|
||||||
ViewLifecycle.WillEnter,
|
ViewLifecycle.WillEnter,
|
||||||
ViewLifecycle.DidEnter,
|
ViewLifecycle.DidEnter,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { PageTwo } from './page-two';
|
import { PageTwo } from './page-two';
|
||||||
|
import { Nav } from '@ionic/angular';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'page-one',
|
selector: 'page-one',
|
||||||
@ -29,9 +30,7 @@ export class PageOne {
|
|||||||
ionViewWillEnterDetection = 'initial';
|
ionViewWillEnterDetection = 'initial';
|
||||||
ionViewDidEnterDetection = 'initial';
|
ionViewDidEnterDetection = 'initial';
|
||||||
|
|
||||||
constructor() {
|
constructor(private nav: Nav) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -55,8 +54,7 @@ export class PageOne {
|
|||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
goToPageTwo() {
|
async goToPageTwo() {
|
||||||
const nav = document.querySelector('ion-nav') as any;
|
await this.nav.push(PageTwo);
|
||||||
nav.push(PageTwo).then(() => console.log('push complete'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
||||||
import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index';
|
import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index';
|
||||||
|
|
||||||
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
|
||||||
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
|
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
|
||||||
|
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
||||||
|
|
||||||
import iosEnterAnimation from './animations/ios.enter';
|
import iosEnterAnimation from './animations/ios.enter';
|
||||||
import iosLeaveAnimation from './animations/ios.leave';
|
import iosLeaveAnimation from './animations/ios.leave';
|
||||||
|
|
||||||
import mdEnterAnimation from './animations/md.enter';
|
import mdEnterAnimation from './animations/md.enter';
|
||||||
import mdLeaveAnimation from './animations/md.leave';
|
import mdLeaveAnimation from './animations/md.leave';
|
||||||
|
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
import { Component, Element, Event, EventEmitter, Listen, Method, Prop } from '@stencil/core';
|
||||||
import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index';
|
import { Animation, AnimationBuilder, Config, CssClassMap } from '../../index';
|
||||||
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
|
||||||
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
|
import { BACKDROP, OverlayEventDetail, OverlayInterface, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
|
||||||
|
import { createThemedClasses, getClassMap } from '../../utils/theme';
|
||||||
|
|
||||||
import iosEnterAnimation from './animations/ios.enter';
|
import iosEnterAnimation from './animations/ios.enter';
|
||||||
import iosLeaveAnimation from './animations/ios.leave';
|
import iosLeaveAnimation from './animations/ios.leave';
|
||||||
|
|
||||||
import mdEnterAnimation from './animations/md.enter';
|
import mdEnterAnimation from './animations/md.enter';
|
||||||
import mdLeaveAnimation from './animations/md.leave';
|
import mdLeaveAnimation from './animations/md.leave';
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user