Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 362e893

Browse files
feat: introduce PageService (#2111)
* feat: introduce PageService * chore: fix typo
1 parent 966ee42 commit 362e893

File tree

4 files changed

+88
-26
lines changed

4 files changed

+88
-26
lines changed

‎e2e/modal-navigation-ng/app/home/home.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { ModalViewComponent } from "../modal-shared/modal-view.component";
1010
import { confirm } from "tns-core-modules/ui/dialogs";
1111

1212
import { AppModule } from "../app.module";
13+
import { PageService } from "nativescript-angular";
1314

1415
@Component({
1516
moduleId: module.id,
@@ -21,7 +22,10 @@ export class HomeComponent {
2122
private modal: ModalDialogService,
2223
private vcRef: ViewContainerRef,
2324
private viewContainerRefService: ViewContainerRefService,
24-
private routerExtension: RouterExtensions) { }
25+
private pageService: PageService,
26+
private routerExtension: RouterExtensions) {
27+
this.pageService.inPage$.subscribe((inPage) => console.log("HomeComponent - inPage", inPage));
28+
}
2529

2630
onNavigateSecond() {
2731
this.routerExtension.navigate(["second"]);

‎nativescript-angular/nativescript.module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { NativeScriptCommonModule } from "./common";
2727
import { NativeScriptRendererFactory } from "./renderer";
2828
import { DetachedLoader } from "./common/detached-loader";
2929
import { throwIfAlreadyLoaded } from "./common/utils";
30-
import { FrameService } from "./platform-providers";
30+
import { FrameService,PageService } from "./platform-providers";
3131

3232
export function errorHandlerFactory() {
3333
return new ErrorHandler();
@@ -41,6 +41,7 @@ export { DetachedLoader };
4141
],
4242
providers: [
4343
FrameService,
44+
PageService,
4445
NativeScriptRendererFactory,
4546
SystemJsNgModuleLoader,
4647
{ provide: APP_ROOT, useValue: true },

‎nativescript-angular/platform-providers.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import { InjectionToken, Injectable } from "@angular/core";
1+
import { InjectionToken, Injectable,OnDestroy } from "@angular/core";
22

3-
import { Frame } from "tns-core-modules/ui/frame";
3+
import { Frame,NavigatedData } from "tns-core-modules/ui/frame";
44
import { View } from "tns-core-modules/ui/core/view";
55
import { Page } from "tns-core-modules/ui/page";
66
import { device, Device } from "tns-core-modules/platform";
7+
import { BehaviorSubject, Subject, Observable } from "rxjs";
8+
import { distinctUntilChanged } from "rxjs/operators";
79

810
export const APP_ROOT_VIEW = new InjectionToken<View>("App Root View");
911
export const DEVICE = new InjectionToken<Device>("platform device");
@@ -71,3 +73,45 @@ export class FrameService {
7173
return topmostFrame;
7274
}
7375
}
76+
77+
@Injectable()
78+
export class PageService implements OnDestroy {
79+
private _inPage$ = new BehaviorSubject<boolean>(false);
80+
private _pageEvents$ = new Subject<NavigatedData>();
81+
82+
get inPage(): boolean { return this._inPage$.value; }
83+
get inPage$(): Observable<boolean> { return this._inPage$.pipe(distinctUntilChanged()); }
84+
get pageEvents$(): Observable<NavigatedData> { return this._pageEvents$.asObservable(); }
85+
constructor(public page: Page) {
86+
if (this.page) {
87+
this.page.on("navigatedFrom", this.pageEvent, this);
88+
this.page.on("navigatedTo", this.pageEvent, this);
89+
this.page.on("navigatingFrom", this.pageEvent, this);
90+
this.page.on("navigatingTo", this.pageEvent, this);
91+
}
92+
}
93+
94+
ngOnDestroy() {
95+
if (this.page) {
96+
this.page.off("navigatedFrom", this.pageEvent, this);
97+
this.page.off("navigatedTo", this.pageEvent, this);
98+
this.page.off("navigatingFrom", this.pageEvent, this);
99+
this.page.off("navigatingTo", this.pageEvent, this);
100+
}
101+
this._inPage$.complete();
102+
this._pageEvents$.complete();
103+
}
104+
105+
private pageEvent(evt: NavigatedData) {
106+
this._pageEvents$.next(evt);
107+
switch (evt.eventName) {
108+
case "navigatedTo":
109+
this._inPage$.next(true);
110+
break;
111+
case "navigatedFrom":
112+
this._inPage$.next(false);
113+
break;
114+
default:
115+
}
116+
}
117+
}

‎nativescript-angular/router/page-router-outlet.ts

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {
33
ComponentFactory, ComponentFactoryResolver, ComponentRef,
44
Directive, Inject, InjectionToken, Injector,
55
OnDestroy, EventEmitter, Output,
6-
Type, ViewContainerRef, ElementRef
6+
Type, ViewContainerRef, ElementRef,InjectFlags
77
} from "@angular/core";
88
import {
99
ActivatedRoute,
@@ -19,7 +19,7 @@ import { profile } from "tns-core-modules/profiling";
1919

2020
import { BehaviorSubject } from "rxjs";
2121

22-
import { DEVICE, PAGE_FACTORY, PageFactory } from "../platform-providers";
22+
import { DEVICE, PAGE_FACTORY, PageFactory,PageService } from "../platform-providers";
2323
import { routerLog as log, routerError as error, isLogEnabled } from "../trace";
2424
import { DetachedLoader } from "../common/detached-loader";
2525
import { ViewUtil } from "../view-util";
@@ -48,23 +48,28 @@ export function destroyComponentRef(componentRef: ComponentRef<any>) {
4848
}
4949
}
5050

51-
class ChildInjector implements Injector {
52-
constructor(
53-
private providers: ProviderMap,
54-
private parent: Injector
55-
) { }
56-
57-
get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T): T {
58-
let localValue = this.providers.get(token);
59-
if (localValue) {
60-
return localValue;
51+
class DestructibleInjector implements Injector {
52+
private refs = new Set<any>();
53+
constructor(private destructableProviders: ProviderSet, private parent: Injector) {
54+
}
55+
get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): T {
56+
const ref = this.parent.get(token, notFoundValue, flags);
57+
if (this.destructableProviders.has(token)) {
58+
this.refs.add(ref);
6159
}
62-
63-
return this.parent.get(token, notFoundValue);
60+
return ref;
61+
}
62+
destroy() {
63+
this.refs.forEach((ref) => {
64+
if (ref.ngOnDestroy instanceof Function) {
65+
ref.ngOnDestroy();
66+
}
67+
});
68+
this.refs.clear();
6469
}
6570
}
6671

67-
type ProviderMap = Map<Type<any> | InjectionToken<any>,any>;
72+
type ProviderSet = Set<Type<any> | InjectionToken<any>>;
6873

6974
/**
7075
* There are cases where multiple activatedRoute nodes should be associated/handled by the same PageRouterOutlet.
@@ -335,16 +340,24 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
335340
componentType: factory.componentType,
336341
});
337342

338-
const providers = new Map();
339-
providers.set(Page, page);
340-
providers.set(Frame, this.frame);
341-
providers.set(PageRoute, new PageRoute(activatedRoute));
342-
providers.set(ActivatedRoute, activatedRoute);
343-
providers.set(ChildrenOutletContexts, this.parentContexts.getOrCreateContext(this.name).children);
343+
const destructables = new Set([PageService]);
344+
const injector = Injector.create({
345+
providers: [
346+
{ provide: PageService, useClass: PageService, deps: [Page] },
347+
{ provide: Page, useValue: page },
348+
{ provide: Frame, useValue: this.frame },
349+
{ provide: PageRoute, useValue: new PageRoute(activatedRoute) },
350+
{ provide: ActivatedRoute, useValue: activatedRoute },
351+
{ provide: ChildrenOutletContexts,
352+
useValue: this.parentContexts.getOrCreateContext(this.name).children }
353+
],
354+
parent: this.location.injector
355+
});
344356

345-
const childInjector = new ChildInjector(providers,this.location.injector);
357+
const childInjector = new DestructibleInjector(destructables,injector);
346358
const loaderRef = this.location.createComponent(
347359
this.detachedLoaderFactory, this.location.length, childInjector, []);
360+
loaderRef.onDestroy(() => childInjector.destroy());
348361
this.changeDetector.markForCheck();
349362

350363
this.activated = loaderRef.instance.loadWithFactory(factory);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /