From 745a539c752c213e21386cc775d3fa6f458b0eb0 Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Thu, 25 Jan 2024 11:53:24 -0500 Subject: [PATCH] refactor: remove NavParams --- BREAKING.md | 25 ++++ .../src/directives/navigation/nav-params.ts | 43 ------- .../common/src/directives/navigation/nav.ts | 5 +- packages/angular/common/src/index.ts | 2 - .../common/src/providers/angular-delegate.ts | 108 ++++-------------- .../src/directives/navigation/ion-nav.ts | 4 +- packages/angular/src/index.ts | 1 - .../angular/src/providers/modal-controller.ts | 5 +- .../src/providers/popover-controller.ts | 5 +- packages/angular/standalone/src/index.ts | 1 - .../angular/standalone/src/navigation/nav.ts | 5 +- .../src/providers/modal-controller.ts | 5 +- .../src/providers/popover-controller.ts | 5 +- 13 files changed, 60 insertions(+), 154 deletions(-) delete mode 100644 packages/angular/common/src/directives/navigation/nav-params.ts diff --git a/BREAKING.md b/BREAKING.md index 22482f89240..a9eca0e5836 100644 --- a/BREAKING.md +++ b/BREAKING.md @@ -22,6 +22,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver - [Datetime](#version-8x-datetime) - [Nav](#version-8x-nav) - [Picker](#version-8x-picker) +- [Angular](#version-8x-angular)

Browser and Platform Support

@@ -143,3 +144,27 @@ This allows components to inherit the color properly when used outside of Ionic - `ion-picker` and `ion-picker-column` have been renamed to `ion-picker-legacy` and `ion-picker-legacy-column`, respectively. This change was made to accommodate the new inline picker component while allowing developers to continue to use the legacy picker during this migration period. - Only the component names have been changed. Usages such as `ion-picker` or `IonPicker` should be changed to `ion-picker-legacy` and `IonPickerLegacy`, respectively. - Non-component usages such as `pickerController` or `useIonPicker` remain unchanged. The new picker displays inline with your page content and does not have equivalents for these non-component usages. + +

Angular

+ +- NavParams has been removed in favor of using Angular's Input API. Components that accessed parameters should ensure that an input is created for each parameter: + +**Old** +```js +import { NavParams } from '@ionic/angular'; + +console.log(this.navParams.get('myProp')); +``` + +**New** +```js +import { Input } from '@angular/core'; + +... + +@Input() myProp: string; + +ngOnInit() { + console.log(this.myProp) +} +``` \ No newline at end of file diff --git a/packages/angular/common/src/directives/navigation/nav-params.ts b/packages/angular/common/src/directives/navigation/nav-params.ts deleted file mode 100644 index a5af4b9d631..00000000000 --- a/packages/angular/common/src/directives/navigation/nav-params.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @description - * NavParams are an object that exists on a page and can contain data for that particular view. - * Similar to how data was pass to a view in V1 with `$stateParams`, NavParams offer a much more flexible - * option with a simple `get` method. - * - * @usage - * ```ts - * import { NavParams } from '@ionic/angular'; - * - * export class MyClass{ - * - * constructor(navParams: NavParams){ - * // userParams is an object we have in our nav-parameters - * navParams.get('userParams'); - * } - * - * } - * ``` - */ -export class NavParams { - constructor(public data: { [key: string]: any } = {}) {} - - /** - * Get the value of a nav-parameter for the current view - * - * ```ts - * import { NavParams } from 'ionic-angular'; - * - * export class MyClass{ - * constructor(public navParams: NavParams){ - * // userParams is an object we have in our nav-parameters - * this.navParams.get('userParams'); - * } - * } - * ``` - * - * @param param Which param you want to look up - */ - get(param: string): T { - return this.data[param]; - } -} diff --git a/packages/angular/common/src/directives/navigation/nav.ts b/packages/angular/common/src/directives/navigation/nav.ts index 585bffc0400..1d24b09c900 100644 --- a/packages/angular/common/src/directives/navigation/nav.ts +++ b/packages/angular/common/src/directives/navigation/nav.ts @@ -1,4 +1,4 @@ -import { ElementRef, Injector, EnvironmentInjector, NgZone, ChangeDetectorRef, Directive } from '@angular/core'; +import { ElementRef, EnvironmentInjector, NgZone, ChangeDetectorRef, Directive } from '@angular/core'; import type { Components } from '@ionic/core'; import { AngularDelegate } from '../../providers/angular-delegate'; @@ -39,14 +39,13 @@ export class IonNav { constructor( ref: ElementRef, environmentInjector: EnvironmentInjector, - injector: Injector, angularDelegate: AngularDelegate, protected z: NgZone, c: ChangeDetectorRef ) { c.detach(); this.el = ref.nativeElement; - ref.nativeElement.delegate = angularDelegate.create(environmentInjector, injector); + ref.nativeElement.delegate = angularDelegate.create(environmentInjector); proxyOutputs(this, this.el, ['ionNavDidChange', 'ionNavWillChange']); } } diff --git a/packages/angular/common/src/index.ts b/packages/angular/common/src/index.ts index 6e5c909acf3..7c8a8bceb79 100644 --- a/packages/angular/common/src/index.ts +++ b/packages/angular/common/src/index.ts @@ -10,8 +10,6 @@ export { bindLifecycleEvents, AngularDelegate } from './providers/angular-delega export type { IonicWindow } from './types/interfaces'; export type { ViewWillEnter, ViewWillLeave, ViewDidEnter, ViewDidLeave } from './types/ionic-lifecycle-hooks'; -export { NavParams } from './directives/navigation/nav-params'; - export { IonPopover } from './overlays/popover'; export { IonModal } from './overlays/modal'; diff --git a/packages/angular/common/src/providers/angular-delegate.ts b/packages/angular/common/src/providers/angular-delegate.ts index c9efeb83319..4cd46e063fe 100644 --- a/packages/angular/common/src/providers/angular-delegate.ts +++ b/packages/angular/common/src/providers/angular-delegate.ts @@ -2,11 +2,9 @@ import { ApplicationRef, NgZone, Injectable, - Injector, EnvironmentInjector, inject, createComponent, - InjectionToken, ComponentRef, } from '@angular/core'; import { @@ -18,8 +16,6 @@ import { LIFECYCLE_WILL_UNLOAD, } from '@ionic/core/components'; -import { NavParams } from '../directives/navigation/nav-params'; - // TODO(FW-2827): types @Injectable() @@ -27,18 +23,8 @@ export class AngularDelegate { private zone = inject(NgZone); private applicationRef = inject(ApplicationRef); - create( - environmentInjector: EnvironmentInjector, - injector: Injector, - elementReferenceKey?: string - ): AngularFrameworkDelegate { - return new AngularFrameworkDelegate( - environmentInjector, - injector, - this.applicationRef, - this.zone, - elementReferenceKey - ); + create(environmentInjector: EnvironmentInjector, elementReferenceKey?: string): AngularFrameworkDelegate { + return new AngularFrameworkDelegate(environmentInjector, this.applicationRef, this.zone, elementReferenceKey); } } @@ -48,7 +34,6 @@ export class AngularFrameworkDelegate implements FrameworkDelegate { constructor( private environmentInjector: EnvironmentInjector, - private injector: Injector, private applicationRef: ApplicationRef, private zone: NgZone, private elementReferenceKey?: string @@ -76,7 +61,6 @@ export class AngularFrameworkDelegate implements FrameworkDelegate { const el = attachView( this.zone, this.environmentInjector, - this.injector, this.applicationRef, this.elRefMap, this.elEventsMap, @@ -113,7 +97,6 @@ export class AngularFrameworkDelegate implements FrameworkDelegate { export const attachView = ( zone: NgZone, environmentInjector: EnvironmentInjector, - injector: Injector, applicationRef: ApplicationRef, elRefMap: WeakMap>, elEventsMap: WeakMap void>, @@ -123,26 +106,8 @@ export const attachView = ( cssClasses: string[] | undefined, elementReferenceKey: string | undefined ): any => { - /** - * Wraps the injector with a custom injector that - * provides NavParams to the component. - * - * NavParams is a legacy feature from Ionic v3 that allows - * Angular developers to provide data to a component - * and access it by providing NavParams as a dependency - * in the constructor. - * - * The modern approach is to access the data directly - * from the component's class instance. - */ - const childInjector = Injector.create({ - providers: getProviders(params), - parent: injector, - }); - const componentRef = createComponent(component, { environmentInjector, - elementInjector: childInjector, }); const instance = componentRef.instance; @@ -164,37 +129,28 @@ export const attachView = ( ); } + const { modal, popover, ...otherParams } = params; + /** + * Any key/value pairs set in componentProps + * must be set as inputs on the component instance. + */ + for (const key in otherParams) { + componentRef.setInput(key, otherParams[key]); + } + /** - * Angular 14.1 added support for setInput - * so we need to fall back to Object.assign - * for Angular 14.0. + * Using setInput will cause an error when + * setting modal/popover on a component that + * does not define them as an input. For backwards + * compatibility purposes we fall back to using + * Object.assign for these properties. */ - if (componentRef.setInput !== undefined) { - const { modal, popover, ...otherParams } = params; - /** - * Any key/value pairs set in componentProps - * must be set as inputs on the component instance. - */ - for (const key in otherParams) { - componentRef.setInput(key, otherParams[key]); - } - - /** - * Using setInput will cause an error when - * setting modal/popover on a component that - * does not define them as an input. For backwards - * compatibility purposes we fall back to using - * Object.assign for these properties. - */ - if (modal !== undefined) { - Object.assign(instance, { modal }); - } - - if (popover !== undefined) { - Object.assign(instance, { popover }); - } - } else { - Object.assign(instance, params); + if (modal !== undefined) { + Object.assign(instance, { modal }); + } + + if (popover !== undefined) { + Object.assign(instance, { popover }); } } if (cssClasses) { @@ -230,23 +186,3 @@ export const bindLifecycleEvents = (zone: NgZone, instance: any, element: HTMLEl return () => unregisters.forEach((fn) => fn()); }); }; - -const NavParamsToken = new InjectionToken('NavParamsToken'); - -const getProviders = (params: { [key: string]: any }) => { - return [ - { - provide: NavParamsToken, - useValue: params, - }, - { - provide: NavParams, - useFactory: provideNavParamsInjectable, - deps: [NavParamsToken], - }, - ]; -}; - -const provideNavParamsInjectable = (params: { [key: string]: any }) => { - return new NavParams(params); -}; diff --git a/packages/angular/src/directives/navigation/ion-nav.ts b/packages/angular/src/directives/navigation/ion-nav.ts index c3dabc41d08..f17346d0cf6 100644 --- a/packages/angular/src/directives/navigation/ion-nav.ts +++ b/packages/angular/src/directives/navigation/ion-nav.ts @@ -1,6 +1,5 @@ import { ElementRef, - Injector, EnvironmentInjector, NgZone, ChangeDetectorRef, @@ -19,11 +18,10 @@ export class IonNav extends IonNavBase { constructor( ref: ElementRef, environmentInjector: EnvironmentInjector, - injector: Injector, angularDelegate: AngularDelegate, z: NgZone, c: ChangeDetectorRef ) { - super(ref, environmentInjector, injector, angularDelegate, z, c); + super(ref, environmentInjector, angularDelegate, z, c); } } diff --git a/packages/angular/src/index.ts b/packages/angular/src/index.ts index da4a6c549c0..8096030ef63 100644 --- a/packages/angular/src/index.ts +++ b/packages/angular/src/index.ts @@ -24,7 +24,6 @@ export { Config, Platform, AngularDelegate, - NavParams, IonicRouteStrategy, ViewWillEnter, ViewWillLeave, diff --git a/packages/angular/src/providers/modal-controller.ts b/packages/angular/src/providers/modal-controller.ts index 51edf69cf36..db3b59ef9af 100644 --- a/packages/angular/src/providers/modal-controller.ts +++ b/packages/angular/src/providers/modal-controller.ts @@ -1,4 +1,4 @@ -import { Injector, Injectable, EnvironmentInjector, inject } from '@angular/core'; +import { Injectable, EnvironmentInjector, inject } from '@angular/core'; import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common'; import type { ModalOptions } from '@ionic/core'; import { modalController } from '@ionic/core'; @@ -6,7 +6,6 @@ import { modalController } from '@ionic/core'; @Injectable() export class ModalController extends OverlayBaseController { private angularDelegate = inject(AngularDelegate); - private injector = inject(Injector); private environmentInjector = inject(EnvironmentInjector); constructor() { @@ -16,7 +15,7 @@ export class ModalController extends OverlayBaseController { return super.create({ ...opts, - delegate: this.angularDelegate.create(this.environmentInjector, this.injector, 'modal'), + delegate: this.angularDelegate.create(this.environmentInjector, 'modal'), }); } } diff --git a/packages/angular/src/providers/popover-controller.ts b/packages/angular/src/providers/popover-controller.ts index 96c5c8d5a82..0e32efdc412 100644 --- a/packages/angular/src/providers/popover-controller.ts +++ b/packages/angular/src/providers/popover-controller.ts @@ -1,11 +1,10 @@ -import { Injector, inject, EnvironmentInjector } from '@angular/core'; +import { inject, EnvironmentInjector } from '@angular/core'; import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common'; import type { PopoverOptions } from '@ionic/core'; import { popoverController } from '@ionic/core'; export class PopoverController extends OverlayBaseController { private angularDelegate = inject(AngularDelegate); - private injector = inject(Injector); private environmentInjector = inject(EnvironmentInjector); constructor() { @@ -15,7 +14,7 @@ export class PopoverController extends OverlayBaseController { return super.create({ ...opts, - delegate: this.angularDelegate.create(this.environmentInjector, this.injector, 'popover'), + delegate: this.angularDelegate.create(this.environmentInjector, 'popover'), }); } } diff --git a/packages/angular/standalone/src/index.ts b/packages/angular/standalone/src/index.ts index 741fef2831f..a47da34dc10 100644 --- a/packages/angular/standalone/src/index.ts +++ b/packages/angular/standalone/src/index.ts @@ -20,7 +20,6 @@ export { NavController, Config, Platform, - NavParams, IonicRouteStrategy, ViewWillEnter, ViewDidEnter, diff --git a/packages/angular/standalone/src/navigation/nav.ts b/packages/angular/standalone/src/navigation/nav.ts index a8c3bb1b009..4c970ef0720 100644 --- a/packages/angular/standalone/src/navigation/nav.ts +++ b/packages/angular/standalone/src/navigation/nav.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, Injector, EnvironmentInjector, NgZone, ChangeDetectorRef } from '@angular/core'; +import { Component, ElementRef, EnvironmentInjector, NgZone, ChangeDetectorRef } from '@angular/core'; import { IonNav as IonNavBase, ProxyCmp, AngularDelegate } from '@ionic/angular/common'; import { defineCustomElement } from '@ionic/core/components/ion-nav.js'; @@ -14,11 +14,10 @@ export class IonNav extends IonNavBase { constructor( ref: ElementRef, environmentInjector: EnvironmentInjector, - injector: Injector, angularDelegate: AngularDelegate, z: NgZone, c: ChangeDetectorRef ) { - super(ref, environmentInjector, injector, angularDelegate, z, c); + super(ref, environmentInjector, angularDelegate, z, c); } } diff --git a/packages/angular/standalone/src/providers/modal-controller.ts b/packages/angular/standalone/src/providers/modal-controller.ts index 07e406ec5d6..fde96781866 100644 --- a/packages/angular/standalone/src/providers/modal-controller.ts +++ b/packages/angular/standalone/src/providers/modal-controller.ts @@ -1,4 +1,4 @@ -import { Injector, Injectable, EnvironmentInjector, inject } from '@angular/core'; +import { Injectable, EnvironmentInjector, inject } from '@angular/core'; import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common'; import type { ModalOptions } from '@ionic/core/components'; import { modalController } from '@ionic/core/components'; @@ -7,7 +7,6 @@ import { defineCustomElement } from '@ionic/core/components/ion-modal.js'; @Injectable() export class ModalController extends OverlayBaseController { private angularDelegate = inject(AngularDelegate); - private injector = inject(Injector); private environmentInjector = inject(EnvironmentInjector); constructor() { @@ -18,7 +17,7 @@ export class ModalController extends OverlayBaseController { return super.create({ ...opts, - delegate: this.angularDelegate.create(this.environmentInjector, this.injector, 'modal'), + delegate: this.angularDelegate.create(this.environmentInjector, 'modal'), }); } } diff --git a/packages/angular/standalone/src/providers/popover-controller.ts b/packages/angular/standalone/src/providers/popover-controller.ts index 395b4dbdb70..cf78ba37040 100644 --- a/packages/angular/standalone/src/providers/popover-controller.ts +++ b/packages/angular/standalone/src/providers/popover-controller.ts @@ -1,4 +1,4 @@ -import { Injector, inject, EnvironmentInjector } from '@angular/core'; +import { inject, EnvironmentInjector } from '@angular/core'; import { AngularDelegate, OverlayBaseController } from '@ionic/angular/common'; import type { PopoverOptions } from '@ionic/core/components'; import { popoverController } from '@ionic/core/components'; @@ -6,7 +6,6 @@ import { defineCustomElement } from '@ionic/core/components/ion-popover.js'; export class PopoverController extends OverlayBaseController { private angularDelegate = inject(AngularDelegate); - private injector = inject(Injector); private environmentInjector = inject(EnvironmentInjector); constructor() { @@ -17,7 +16,7 @@ export class PopoverController extends OverlayBaseController { return super.create({ ...opts, - delegate: this.angularDelegate.create(this.environmentInjector, this.injector, 'popover'), + delegate: this.angularDelegate.create(this.environmentInjector, 'popover'), }); } }