diff --git a/docs/en/framework/ui/angular/abp-window-service.md b/docs/en/framework/ui/angular/abp-window-service.md index bc060f79b5..bd55c4d2d1 100644 --- a/docs/en/framework/ui/angular/abp-window-service.md +++ b/docs/en/framework/ui/angular/abp-window-service.md @@ -13,10 +13,9 @@ Firstly, ensure that the service is injected into the component or any other Ang ```js import { AbpWindowService } from '@abp/ng.core'; +import { inject } from '@angular/core'; -constructor(private abpWindowService: AbpWindowService) { } -// or -// private abpWindowService = inject(AbpWindowService) +private abpWindowService = inject(AbpWindowService) ``` ### Downloading a Blob diff --git a/docs/en/framework/ui/angular/component-replacement.md b/docs/en/framework/ui/angular/component-replacement.md index e547b73531..e1a3af734f 100644 --- a/docs/en/framework/ui/angular/component-replacement.md +++ b/docs/en/framework/ui/angular/component-replacement.md @@ -13,13 +13,14 @@ Then, open the `app.component.ts` and execute the `add` method of `ReplaceableCo ```js import { ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { eIdentityComponents } from '@abp/ng.identity'; // imported eIdentityComponents enum +import { Component, inject } from '@angular/core'; //... @Component(/* component metadata */) export class AppComponent { - constructor( - private replaceableComponents: ReplaceableComponentsService, // injected the service - ) { + private replaceableComponents = inject(ReplaceableComponentsService); + + constructor() { this.replaceableComponents.add({ component: YourNewRoleComponent, key: eIdentityComponents.Roles, @@ -56,12 +57,13 @@ Open `app.component.ts` in `src/app` folder and modify it as shown below: import { ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeBasicComponents enum for component keys import { MyApplicationLayoutComponent } from './my-application-layout/my-application-layout.component'; // imported MyApplicationLayoutComponent +import { Component, inject } from '@angular/core'; @Component(/* component metadata */) export class AppComponent { - constructor( - private replaceableComponents: ReplaceableComponentsService, // injected the service - ) { + private replaceableComponents = inject(ReplaceableComponentsService); + + constructor() { this.replaceableComponents.add({ component: MyApplicationLayoutComponent, key: eThemeBasicComponents.ApplicationLayout, @@ -268,15 +270,15 @@ import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeB @Component(/* component metadata */) export class AppComponent implements OnInit { - constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService + private replaceableComponents = inject(ReplaceableComponentsService); ngOnInit() { //... this.replaceableComponents.add({ - component: LogoComponent, - key: eThemeBasicComponents.Logo, - }); + component: LogoComponent, + key: eThemeBasicComponents.Logo, + }); } } ``` @@ -454,15 +456,15 @@ import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeB @Component(/* component metadata */) export class AppComponent implements OnInit { - constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService + private replaceableComponents = inject(ReplaceableComponentsService); ngOnInit() { //... this.replaceableComponents.add({ - component: RoutesComponent, - key: eThemeBasicComponents.Routes, - }); + component: RoutesComponent, + key: eThemeBasicComponents.Routes, + }); } } ``` @@ -493,7 +495,7 @@ import { SessionStateService, LocalizationPipe } from '@abp/ng.core'; -import { Component, Inject } from '@angular/core'; +import { Component, inject, Inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; @@ -512,9 +514,13 @@ import snq from 'snq'; ] }) export class NavItemsComponent { + private configState = inject(ConfigStateService); + private authService = inject(AuthService); + private sessionState = inject(SessionStateService); + @Inject(NAVIGATE_TO_MANAGE_PROFILE) public navigateToManageProfile: any; + currentUser$: Observable = this.configState.getOne$('currentUser'); selectedTenant$ = this.sessionState.getTenant$(); - languages$: Observable = this.configState.getDeep$('localization.languages'); get smallScreen(): boolean { @@ -547,13 +553,6 @@ export class NavItemsComponent { return this.sessionState.getLanguage(); } - constructor( - @Inject(NAVIGATE_TO_MANAGE_PROFILE) public navigateToManageProfile, - private configState: ConfigStateService, - private authService: AuthService, - private sessionState: SessionStateService - ) {} - onChangeLang(cultureName: string) { this.sessionState.setLanguage(cultureName); } @@ -669,15 +668,15 @@ import { eThemeBasicComponents } from '@abp/ng.theme.basic'; // imported eThemeB @Component(/* component metadata */) export class AppComponent implements OnInit { - constructor(..., private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService + private replaceableComponents = inject(ReplaceableComponentsService); ngOnInit() { //... this.replaceableComponents.add({ - component: NavItemsComponent, - key: eThemeBasicComponents.NavItems, - }); + component: NavItemsComponent, + key: eThemeBasicComponents.NavItems, + }); } } ``` diff --git a/docs/en/framework/ui/angular/config-state-service.md b/docs/en/framework/ui/angular/config-state-service.md index f0d3418898..72200ed696 100644 --- a/docs/en/framework/ui/angular/config-state-service.md +++ b/docs/en/framework/ui/angular/config-state-service.md @@ -8,12 +8,13 @@ In order to use the `ConfigStateService` you must inject it in your class as a d ```js import { ConfigStateService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - private config = inject(ConfigStateService); + private config = inject(ConfigStateService); } ``` @@ -126,10 +127,12 @@ You can get the application configuration response and set the `ConfigStateServi ```js import { AbpApplicationConfigurationService, ConfigStateService } from '@abp/ng.core'; +import { inject } from '@angular/core'; private abpApplicationConfigurationService = inject(AbpApplicationConfigurationService); private config = inject(ConfigStateService); + constructor() { this.abpApplicationConfigurationService.get({ includeLocalizationResources: false }).subscribe(config => { this.config.setState(config); diff --git a/docs/en/framework/ui/angular/confirmation-service.md b/docs/en/framework/ui/angular/confirmation-service.md index 3ff84f7dbe..96d05387bd 100644 --- a/docs/en/framework/ui/angular/confirmation-service.md +++ b/docs/en/framework/ui/angular/confirmation-service.md @@ -8,12 +8,13 @@ You do not have to provide the `ConfirmationService` at component level, because ```js import { ConfirmationService } from '@abp/ng.theme.shared'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private confirmation: ConfirmationService) {} + private confirmation = inject(ConfirmationService); } ``` @@ -36,8 +37,10 @@ You can subscribe to the confirmation closing event like below: ```js import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared'; +import { inject } from '@angular/core'; -constructor(private confirmation: ConfirmationService) {} +// inside the class: +private confirmation = inject(ConfirmationService); this.confirmation .warn('::WillBeDeleted', { key: '::AreYouSure', defaultValue: 'Are you sure?' }) @@ -132,7 +135,10 @@ this.confirmation.clear(); You can change icons with the `withConfirmationIcon()` method inside `provideAbpThemeShared` function in the app.config.ts. The changes will affect all confirmation popup in the project. ```ts -import { provideAbpThemeShared, withConfirmationIcon } from '@abp/ng.theme.shared'; +import { + provideAbpThemeShared, + withConfirmationIcon, +} from "@abp/ng.theme.shared"; export const appConfig: ApplicationConfig = { providers: [ diff --git a/docs/en/framework/ui/angular/content-projection-service.md b/docs/en/framework/ui/angular/content-projection-service.md index 0308b0353a..ca6c9d2144 100644 --- a/docs/en/framework/ui/angular/content-projection-service.md +++ b/docs/en/framework/ui/angular/content-projection-service.md @@ -8,12 +8,13 @@ You do not have to provide the `ContentProjectionService` at module or component ```js import { ContentProjectionService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private contentProjectionService: ContentProjectionService) {} + private contentProjectionService = inject(ContentProjectionService); } ``` diff --git a/docs/en/framework/ui/angular/dom-insertion-service.md b/docs/en/framework/ui/angular/dom-insertion-service.md index 43d7d16ed1..0e084d7a4a 100644 --- a/docs/en/framework/ui/angular/dom-insertion-service.md +++ b/docs/en/framework/ui/angular/dom-insertion-service.md @@ -8,12 +8,13 @@ You do not have to provide the `DomInsertionService` at module or component leve ```js import { DomInsertionService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private domInsertionService: DomInsertionService) {} + private domInsertionService = inject(DomInsertionService); } ``` @@ -27,12 +28,13 @@ The first parameter of `insertContent` method expects a `ContentStrategy`. If yo ```js import { DomInsertionService, CONTENT_STRATEGY } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private domInsertionService: DomInsertionService) {} + private domInsertionService = inject(DomInsertionService); ngOnInit() { const scriptElement = this.domInsertionService.insertContent( @@ -54,12 +56,13 @@ If you pass a `StyleContentStrategy` instance as the first parameter of `insertC ```js import { DomInsertionService, CONTENT_STRATEGY } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private domInsertionService: DomInsertionService) {} + private domInsertionService = inject(DomInsertionService); ngOnInit() { const styleElement = this.domInsertionService.insertContent( @@ -81,15 +84,15 @@ If you pass the inserted `HTMLScriptElement` or `HTMLStyleElement` element as th ```js import { DomInsertionService, CONTENT_STRATEGY } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { + private domInsertionService = inject(DomInsertionService); private styleElement: HTMLStyleElement; - constructor(private domInsertionService: DomInsertionService) {} - ngOnInit() { this.styleElement = this.domInsertionService.insertContent( CONTENT_STRATEGY.AppendStyleToHead('body {margin: 0;}') diff --git a/docs/en/framework/ui/angular/environment.md b/docs/en/framework/ui/angular/environment.md index 8925b2b9d6..e32fc98aae 100644 --- a/docs/en/framework/ui/angular/environment.md +++ b/docs/en/framework/ui/angular/environment.md @@ -132,7 +132,8 @@ export const appConfig: ApplicationConfig = { In order to use the `EnvironmentService` you must inject it in your class as a dependency. ```js -import { EnvironmentService } from '@abp/ng.core'; +import { EnvironmentService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ diff --git a/docs/en/framework/ui/angular/features.md b/docs/en/framework/ui/angular/features.md index 337f034aad..7e71632b1e 100644 --- a/docs/en/framework/ui/angular/features.md +++ b/docs/en/framework/ui/angular/features.md @@ -10,12 +10,13 @@ To use the `ConfigStateService`, you must inject it in your class as a dependenc ```js import { ConfigStateService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private config: ConfigStateService) {} + private config = inject(ConfigStateService); } ``` diff --git a/docs/en/framework/ui/angular/global-features.md b/docs/en/framework/ui/angular/global-features.md index b9b167d176..5214ea2906 100644 --- a/docs/en/framework/ui/angular/global-features.md +++ b/docs/en/framework/ui/angular/global-features.md @@ -9,14 +9,14 @@ The `ConfigStateService.getGlobalFeatures` API allows you to get the enabled fea ````js import { ConfigStateService } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent implements OnInit { - constructor(private config: ConfigStateService) {} - + private config = inject(ConfigStateService); + ngOnInit(): void { // Gets all enabled global features. const getGlobalFeatures = this.config.getGlobalFeatures(); @@ -44,4 +44,3 @@ class DemoComponent implements OnInit { } } - diff --git a/docs/en/framework/ui/angular/how-replaceable-components-work-with-extensions.md b/docs/en/framework/ui/angular/how-replaceable-components-work-with-extensions.md index 11a7f6dfb8..3e6d9ab328 100644 --- a/docs/en/framework/ui/angular/how-replaceable-components-work-with-extensions.md +++ b/docs/en/framework/ui/angular/how-replaceable-components-work-with-extensions.md @@ -17,6 +17,10 @@ yarn ng generate component my-roles/my-roles --flat --export Open the generated `src/app/my-roles/my-roles.component.ts` file and replace its content with the following: ```js +import { Component, Injector, inject, OnInit } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { finalize } from 'rxjs/operators'; + import { ListService, PagedAndSortedResultRequestDto, PagedResultDto } from '@abp/ng.core'; import { eIdentityComponents, RolesComponent } from '@abp/ng.identity'; import { IdentityRoleDto, IdentityRoleService } from '@abp/ng.identity/proxy'; @@ -27,9 +31,6 @@ import { FormPropData, generateFormFromProps } from '@abp/ng.components/extensible'; -import { Component, Injector, OnInit } from '@angular/core'; -import { FormGroup } from '@angular/forms'; -import { finalize } from 'rxjs/operators'; @Component({ selector: 'app-my-roles', @@ -40,13 +41,18 @@ import { finalize } from 'rxjs/operators'; provide: EXTENSIONS_IDENTIFIER, useValue: eIdentityComponents.Roles, }, - { - provide: RolesComponent, - useExisting: MyRolesComponent - } + { + provide: RolesComponent, + useExisting: MyRolesComponent, + }, ], }) export class MyRolesComponent implements OnInit { + public readonly list = inject>(ListService); + protected readonly confirmationService = inject(ConfirmationService); + protected readonly injector = inject(Injector); + protected readonly service = inject(IdentityRoleService); + data: PagedResultDto = { items: [], totalCount: 0 }; form: FormGroup; @@ -63,17 +69,10 @@ export class MyRolesComponent implements OnInit { permissionManagementKey = ePermissionManagementComponents.PermissionManagement; - onVisiblePermissionChange = event => { + onVisiblePermissionChange = (event) => { this.visiblePermissions = event; }; - constructor( - public readonly list: ListService, - protected confirmationService: ConfirmationService, - protected injector: Injector, - protected service: IdentityRoleService, - ) {} - ngOnInit() { this.hookToQuery(); } @@ -253,13 +252,18 @@ export class MyRolesModule {} As the last step, it is needs to be replaced the `RolesComponent` with the `MyRolesComponent`. Open the `app.component.ts` and modify its content as shown below: ```js +import { Component, inject } from '@angular/core'; import { ReplaceableComponentsService } from '@abp/ng.core'; import { eIdentityComponents } from '@abp/ng.identity'; import { MyRolesComponent } from './my-roles/my-roles.component'; -@Component(/* component metadata */) +@Component({ + // component metadata +}) export class AppComponent { - constructor(private replaceableComponents: ReplaceableComponentsService) { + private replaceableComponents = inject(ReplaceableComponentsService); + + constructor() { this.replaceableComponents.add({ component: MyRolesComponent, key: eIdentityComponents.Roles }); } } diff --git a/docs/en/framework/ui/angular/http-error-reporter-service.md b/docs/en/framework/ui/angular/http-error-reporter-service.md index 5e85fc95dc..e7f9a6f5a8 100644 --- a/docs/en/framework/ui/angular/http-error-reporter-service.md +++ b/docs/en/framework/ui/angular/http-error-reporter-service.md @@ -7,13 +7,14 @@ See the example below to learn how to report an error: ```ts import { HttpErrorReporterService } from '@abp/ng.core'; import { HttpClient } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { of } from 'rxjs'; import { catchError } from 'rxjs/operators'; @Injectable() export class SomeService { - constructor(private http: HttpClient, private httpErrorReporter: HttpErrorReporterService) {} + private http = inject(HttpClient); + private httpErrorReporter = inject(HttpErrorReporterService); getData() { return this.http.get('http://example.com/get-data').pipe( @@ -31,17 +32,19 @@ See the following example to learn listening the reported errors: ```ts import { HttpErrorReporterService } from '@abp/ng.core'; import { HttpErrorResponse } from '@angular/common/http'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable() export class MyErrorHandler { - constructor(private httpErrorReporter: HttpErrorReporterService) { + private httpErrorReporter = inject(HttpErrorReporterService); + + constructor() { this.handleErrors(); } handleErrors() { this.httpErrorReporter.reporter$.subscribe((err: HttpErrorResponse) => { - // handle the errors here + // handle the errors here }); } } diff --git a/docs/en/framework/ui/angular/http-requests.md b/docs/en/framework/ui/angular/http-requests.md index ff73c6ee52..928a4f600b 100644 --- a/docs/en/framework/ui/angular/http-requests.md +++ b/docs/en/framework/ui/angular/http-requests.md @@ -31,12 +31,13 @@ In order to use the `RestService`, you must inject it in your class as a depende ```js import { RestService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Injectable({ /* class metadata here */ }) class DemoService { - constructor(private rest: RestService) {} + private rest = inject(RestService); } ``` diff --git a/docs/en/framework/ui/angular/lazy-load-service.md b/docs/en/framework/ui/angular/lazy-load-service.md index 8dedddfe7c..339f0f656b 100644 --- a/docs/en/framework/ui/angular/lazy-load-service.md +++ b/docs/en/framework/ui/angular/lazy-load-service.md @@ -11,12 +11,13 @@ You do not have to provide the `LazyLoadService` at module or component level, b ```js import { LazyLoadService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private lazyLoadService: LazyLoadService) {} + private lazyLoadService = inject(LazyLoadService); } ``` @@ -35,6 +36,7 @@ The first parameter of `load` method expects a `LoadingStrategy`. If you pass a ```js import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ template: ` @@ -42,11 +44,11 @@ import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; ` }) class DemoComponent { + private lazyLoadService = inject(LazyLoadService); + libraryLoaded$ = this.lazyLoadService.load( LOADING_STRATEGY.AppendAnonymousScriptToHead('/assets/some-library.js'), ); - - constructor(private lazyLoadService: LazyLoadService) {} } ``` @@ -64,6 +66,7 @@ If you pass a `StyleLoadingStrategy` instance as the first parameter of `load` m ```js import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ template: ` @@ -71,11 +74,11 @@ import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; ` }) class DemoComponent { + private lazyLoadService = inject(LazyLoadService); + stylesLoaded$ = this.lazyLoadService.load( LOADING_STRATEGY.AppendAnonymousStyleToHead('/assets/some-styles.css'), ); - - constructor(private lazyLoadService: LazyLoadService) {} } ``` @@ -114,7 +117,8 @@ A common usecase is **loading multiple scripts and/or styles before using a feat ```js import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; -import { frokJoin } from 'rxjs'; +import { forkJoin } from 'rxjs'; +import { inject } from '@angular/core'; @Component({ template: ` @@ -122,6 +126,8 @@ import { frokJoin } from 'rxjs'; ` }) class DemoComponent { + private lazyLoad = inject(LazyLoadService); + private stylesLoaded$ = forkJoin( this.lazyLoad.load( LOADING_STRATEGY.PrependAnonymousStyleToHead('/assets/library-dark-theme.css'), @@ -141,8 +147,6 @@ class DemoComponent { ); scriptsAndStylesLoaded$ = forkJoin(this.scriptsLoaded$, this.stylesLoaded$); - - constructor(private lazyLoadService: LazyLoadService) {} } ``` @@ -156,6 +160,7 @@ Another frequent usecase is **loading dependent scripts in order**: ```js import { LazyLoadService, LOADING_STRATEGY } from '@abp/ng.core'; import { concat } from 'rxjs'; +import { inject } from '@angular/core'; @Component({ template: ` @@ -163,6 +168,8 @@ import { concat } from 'rxjs'; ` }) class DemoComponent { + private lazyLoad = inject(LazyLoadService); + scriptsLoaded$ = concat( this.lazyLoad.load( LOADING_STRATEGY.PrependAnonymousScriptToHead('/assets/library.js'), @@ -171,8 +178,6 @@ class DemoComponent { LOADING_STRATEGY.AppendAnonymousScriptToHead('/assets/script-that-requires-library.js'), ), ); - - constructor(private lazyLoadService: LazyLoadService) {} } ``` diff --git a/docs/en/framework/ui/angular/list-service.md b/docs/en/framework/ui/angular/list-service.md index b5b1af66ae..c6b0a2a35c 100644 --- a/docs/en/framework/ui/angular/list-service.md +++ b/docs/en/framework/ui/angular/list-service.md @@ -12,6 +12,7 @@ import { ListService } from '@abp/ng.core'; import { BookDto } from '../models'; import { BookService } from '../services'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ @@ -32,10 +33,10 @@ class BookComponent { items: BookDto[] = []; count = 0; - constructor( - public readonly list: ListService, - private bookService: BookService, - ) { + public readonly list = inject(ListService); + private bookService = inject(BookService); + + constructor() { // change ListService defaults here this.list.maxResultCount = 20; } @@ -78,7 +79,7 @@ You can extend the query parameter of the `ListService`'s `hookToQuery` method. Firstly, you should pass your own type to `ListService` as shown below: ```typescript -constructor(public readonly list: ListService) { } +public readonly list = inject(ListService); ``` Then update the `bookStreamCreator` constant like following: diff --git a/docs/en/framework/ui/angular/localization.md b/docs/en/framework/ui/angular/localization.md index 6d4b3ab411..5d14eb0333 100644 --- a/docs/en/framework/ui/angular/localization.md +++ b/docs/en/framework/ui/angular/localization.md @@ -71,9 +71,10 @@ First of all you should import the `LocalizationService` from **@abp/ng.core** ```js import { LocalizationService } from '@abp/ng.core'; +import { inject } from '@angular/core'; class MyClass { - constructor(private localizationService: LocalizationService) {} + private localizationService = inject(LocalizationService); } ``` diff --git a/docs/en/framework/ui/angular/modal.md b/docs/en/framework/ui/angular/modal.md index 5b091e07e2..7ff20d885a 100644 --- a/docs/en/framework/ui/angular/modal.md +++ b/docs/en/framework/ui/angular/modal.md @@ -132,12 +132,12 @@ See an example form inside a modal: import { Component } from '@angular/core'; import { FormBuilder, Validators } from '@angular/forms'; +import { inject } from '@angular/core'; @Component(/* component metadata */) export class BookComponent { private fb = inject(FormBuilder); private service = inject(BookService); - form = this.fb.group({ author: [null, [Validators.required]], name: [null, [Validators.required]], @@ -147,7 +147,6 @@ export class BookComponent { }); inProgress: boolean; - isModalOpen: boolean; save() { diff --git a/docs/en/framework/ui/angular/modifying-the-menu.md b/docs/en/framework/ui/angular/modifying-the-menu.md index 21e1793c47..087f022dc3 100644 --- a/docs/en/framework/ui/angular/modifying-the-menu.md +++ b/docs/en/framework/ui/angular/modifying-the-menu.md @@ -47,12 +47,14 @@ You can add routes to the menu by calling the `add` method of `RoutesService`. I ```js import { RoutesService, eLayoutType } from '@abp/ng.core'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; @Component(/* component metadata */) export class AppComponent { - constructor(routes: RoutesService) { - routes.add([ + private routes = inject(RoutesService); + + constructor() { + this.routes.add([ { path: '/your-path', name: 'Your navigation', @@ -138,15 +140,16 @@ To get the route items as grouped we can use the `groupedVisible` (or Observable ```js import { ABP, RoutesService, RouteGroup } from "@abp/ng.core"; -import { Component } from "@angular/core"; +import { Component, inject } from "@angular/core"; +import { Observable } from "rxjs"; @Component(/* component metadata */) export class AppComponent { + private routes = inject(RoutesService); + visible: RouteGroup[] | undefined = this.routes.groupedVisible; - //Or - visible$:Observable[] | undefined> = this.routes.groupedVisible$; - - constructor(private routes: RoutesService) {} + // Or + visible$: Observable[] | undefined> = this.routes.groupedVisible$; } ``` @@ -177,12 +180,14 @@ export const appConfig: ApplicationConfig = { ```typescript import { RoutesService } from '@abp/ng.core'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; @Component(/* component metadata */) export class AppComponent { - constructor(private routes: RoutesService) { - routes.setSingularizeStatus(false); + private routes = inject(RoutesService); + + constructor() { + this.routes.setSingularizeStatus(false); } } ``` @@ -311,7 +316,7 @@ You can add elements to the right part of the menu by calling the `addItems` met ```js import { NavItemsService } from '@abp/ng.theme.shared'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; @Component({ template: ` @@ -323,8 +328,10 @@ export class MySearchInputComponent {} @Component(/* component metadata */) export class AppComponent { - constructor(private navItems: NavItemsService) { - navItems.addItems([ + private navItems = inject(NavItemsService); + + constructor() { + this.navItems.addItems([ { id: 'MySearchInput', order: 1, @@ -353,13 +360,15 @@ The `patchItem` method of `NavItemsService` finds an element by its `id` propert ```js export class AppComponent { - constructor(private navItems: NavItemsService) { - navItems.patchItem(eThemeBasicComponents.Languages, { + private navItems = inject(NavItemsService); + + constructor() { + this.navItems.patchItem(eThemeBasicComponents.Languages, { requiredPolicy: 'new policy here', order: 1, }); - navItems.removeItem(eThemeBasicComponents.CurrentUser); + this.navItems.removeItem(eThemeBasicComponents.CurrentUser); } } ``` diff --git a/docs/en/framework/ui/angular/page-alerts.md b/docs/en/framework/ui/angular/page-alerts.md index 4275b45f54..8af18dbc4d 100644 --- a/docs/en/framework/ui/angular/page-alerts.md +++ b/docs/en/framework/ui/angular/page-alerts.md @@ -8,12 +8,13 @@ You can simply import `PageAlertService` from `@abp/ng.theme.shared` and utilize ```js import { PageAlertService } from '@abp/ng.theme.shared'; +import { inject } from '@angular/core'; @Component({ // ... }) export class MyComponent { - constructor(private service: PageAlertService) {} + private service = inject(PageAlertService); showWarning() { this.service.show({ diff --git a/docs/en/framework/ui/angular/page-component.md b/docs/en/framework/ui/angular/page-component.md index f190597fcf..86fd1b8aea 100644 --- a/docs/en/framework/ui/angular/page-component.md +++ b/docs/en/framework/ui/angular/page-component.md @@ -175,7 +175,7 @@ export class MyPageRenderStrategy implements PageRenderStrategy { * shouldRender can also return an Observable which means * an async service can be used within. - constructor(private service: SomeAsyncService) {} + service = inject(SomeAsyncService) shouldRender(type: string) { return this.service.checkTypeAsync(type).pipe(map(val => val.isTrue())); diff --git a/docs/en/framework/ui/angular/permission-management-component-replacement.md b/docs/en/framework/ui/angular/permission-management-component-replacement.md index 677100381a..c6041cc784 100644 --- a/docs/en/framework/ui/angular/permission-management-component-replacement.md +++ b/docs/en/framework/ui/angular/permission-management-component-replacement.md @@ -19,7 +19,7 @@ import { import { LocaleDirection } from '@abp/ng.theme.shared'; import { Component, - EventEmitter, Inject, Input, Optional, Output, TrackByFunction + EventEmitter, Inject, inject, Input, Optional, Output, TrackByFunction } from '@angular/core'; import { of } from 'rxjs'; import { finalize, switchMap, tap } from 'rxjs/operators'; @@ -42,16 +42,18 @@ type PermissionWithStyle = PermissionGrantInfoDto & { }) export class PermissionManagementComponent implements - PermissionManagement.PermissionManagementComponentInputs, - PermissionManagement.PermissionManagementComponentOutputs { + PermissionManagement.PermissionManagementComponentInputs, + PermissionManagement.PermissionManagementComponentOutputs { + + private readonly service = inject(PermissionsService); + private readonly configState = inject(ConfigStateService); + protected _providerName: string; @Input() get providerName(): string { if (this.replaceableData) return this.replaceableData.inputs.providerName; - return this._providerName; } - set providerName(value: string) { this._providerName = value; } @@ -60,10 +62,8 @@ export class PermissionManagementComponent @Input() get providerKey(): string { if (this.replaceableData) return this.replaceableData.inputs.providerKey; - return this._providerKey; } - set providerKey(value: string) { this._providerKey = value; } @@ -72,10 +72,8 @@ export class PermissionManagementComponent @Input() get hideBadges(): boolean { if (this.replaceableData) return this.replaceableData.inputs.hideBadges; - return this._hideBadges; } - set hideBadges(value: boolean) { this._hideBadges = value; } @@ -85,7 +83,6 @@ export class PermissionManagementComponent get visible(): boolean { return this._visible; } - set visible(value: boolean) { if (value === this._visible) return; @@ -106,15 +103,10 @@ export class PermissionManagementComponent @Output() readonly visibleChange = new EventEmitter(); data: GetPermissionListResultDto = { groups: [], entityDisplayName: null }; - selectedGroup: PermissionGroupDto; - permissions: PermissionGrantInfoDto[] = []; - selectThisTab = false; - selectAllTab = false; - modalBusy = false; trackByFn: TrackByFunction = (_, item) => item.name; @@ -142,7 +134,6 @@ export class PermissionManagementComponent get isVisible(): boolean { if (!this.replaceableData) return this.visible; - return this.replaceableData.inputs.visible; } @@ -152,9 +143,7 @@ export class PermissionManagementComponent public replaceableData: ReplaceableComponents.ReplaceableTemplateData< PermissionManagement.PermissionManagementComponentInputs, PermissionManagement.PermissionManagementComponentOutputs - >, - private service: PermissionsService, - private configState: ConfigStateService + > ) {} getChecked(name: string) { @@ -162,17 +151,11 @@ export class PermissionManagementComponent } isGrantedByOtherProviderName(grantedProviders: ProviderInfoDto[]): boolean { - if (grantedProviders.length) { - return grantedProviders.findIndex(p => p.providerName !== this.providerName) > -1; - } - return false; + return grantedProviders?.some(p => p.providerName !== this.providerName); } onClickCheckbox(clickedPermission: PermissionGrantInfoDto, value) { - if ( - clickedPermission.isGranted && - this.isGrantedByOtherProviderName(clickedPermission.grantedProviders) - ) + if (clickedPermission.isGranted && this.isGrantedByOtherProviderName(clickedPermission.grantedProviders)) return; setTimeout(() => { @@ -184,7 +167,6 @@ export class PermissionManagementComponent } else if (clickedPermission.parentName === per.name && !clickedPermission.isGranted) { return { ...per, isGranted: true }; } - return per; }); @@ -255,16 +237,11 @@ export class PermissionManagementComponent this.setTabCheckboxState(); } - submit() { const unchangedPermissions = getPermissions(this.data.groups); - const changedPermissions: UpdatePermissionDto[] = this.permissions .filter(per => - unchangedPermissions.find(unchanged => unchanged.name === per.name).isGranted === - per.isGranted - ? false - : true, + unchangedPermissions.find(unchanged => unchanged.name === per.name).isGranted !== per.isGranted ) .map(({ name, isGranted }) => ({ name, isGranted })); @@ -321,26 +298,23 @@ export class PermissionManagementComponent this.replaceableData.outputs.visibleChange(visible); } } - + shouldFetchAppConfig() { const currentUser = this.configState.getOne('currentUser') as CurrentUserDto; if (this.providerName === 'R') return currentUser.roles.some(role => role === this.providerKey); - if (this.providerName === 'U') return currentUser.id === this.providerKey; return false; } } -function findMargin(permissions: PermissionGrantInfoDto[], permission: PermissionGrantInfoDto) { +function findMargin(permissions: PermissionGrantInfoDto[], permission: PermissionGrantInfoDto): number { const parentPermission = permissions.find(per => per.name === permission.parentName); - if (parentPermission && parentPermission.parentName) { let margin = 20; - return (margin += findMargin(permissions, parentPermission)); + return margin + findMargin(permissions, parentPermission); } - return parentPermission ? 20 : 0; } @@ -461,12 +435,12 @@ Open `app.component.ts` in `src/app` folder and modify it as shown below: ```js import { ReplaceableComponentsService } from '@abp/ng.core'; import { ePermissionManagementComponents } from '@abp/ng.permission-management'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { PermissionManagementComponent } from './permission-management/permission-management.component'; //... export class AppComponent implements OnInit { - constructor(private replaceableComponents: ReplaceableComponentsService) {} // injected ReplaceableComponentsService + private readonly replaceableComponents = inject(ReplaceableComponentsService); // injected ReplaceableComponentsService ngOnInit() { this.replaceableComponents.add({ diff --git a/docs/en/framework/ui/angular/permission-management.md b/docs/en/framework/ui/angular/permission-management.md index 5d3ed64351..cb22b5863a 100644 --- a/docs/en/framework/ui/angular/permission-management.md +++ b/docs/en/framework/ui/angular/permission-management.md @@ -8,9 +8,10 @@ You can get permission as boolean value: ```js import { PermissionService } from '@abp/ng.core'; +import { inject } from '@angular/core'; export class YourComponent { - constructor(private permissionService: PermissionService) {} + private permissionService = inject(PermissionService); ngOnInit(): void { const canCreate = this.permissionService.getGrantedPolicy('AbpIdentity.Roles.Create'); @@ -83,14 +84,14 @@ In some cases, a custom permission management may be needed. All you need to do ```js import { ConfigStateService, PermissionService } from '@abp/ng.core'; -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class CustomPermissionService extends PermissionService { - constructor(configStateService: ConfigStateService) { - super(configStateService); + constructor() { + super(inject(ConfigStateService)); } // This is an example to show how to override the methods diff --git a/docs/en/framework/ui/angular/router-events.md b/docs/en/framework/ui/angular/router-events.md index 817667cfb9..a41874ec10 100644 --- a/docs/en/framework/ui/angular/router-events.md +++ b/docs/en/framework/ui/angular/router-events.md @@ -14,9 +14,12 @@ import { Router, } from '@angular/router'; import { filter } from 'rxjs/operators'; +import { inject, Injectable } from '@angular/core'; @Injectable() class SomeService { + private router = inject(Router); + navigationFinish$ = this.router.events.pipe( filter( event => @@ -26,8 +29,6 @@ class SomeService { ), ); /* Observable */ - - constructor(private router: Router) {} } ``` @@ -38,10 +39,10 @@ import { RouterEvents } from '@abp/ng.core'; @Injectable() class SomeService { + private routerEvents = inject(RouterEvents); + navigationFinish$ = this.routerEvents.getNavigationEvents('End', 'Error', 'Cancel'); /* Observable */ - - constructor(private routerEvents: RouterEvents) {} } ``` @@ -62,6 +63,8 @@ import { mapTo } from 'rxjs/operators'; @Injectable() class SomeService { + private routerEvents = inject(RouterEvents); + navigationStart$ = this.routerEvents.getNavigationEvents('Start'); /* Observable */ @@ -73,8 +76,6 @@ class SomeService { this.navigationFinish$.pipe(mapTo(false)), ); /* Observable */ - - constructor(private routerEvents: RouterEvents) {} } ``` @@ -88,6 +89,8 @@ import { map } from 'rxjs/operators'; @Injectable() class SomeService { + private routerEvents = inject(RouterEvents); + navigationEvent$ = this.routerEvents.getAllNavigationEvents(); /* Observable */ @@ -95,8 +98,6 @@ class SomeService { map(event => event instanceof NavigationStart), ); /* Observable */ - - constructor(private routerEvents: RouterEvents) {} } ``` @@ -127,7 +128,7 @@ class SomeService { ### How to Get Specific Router Events -You can use `getEvents` to get a stream of router events matching given event constructors. +You can use `getEvents` to get a stream of router events matching given event classes. ```js import { RouterEvents } from '@abp/ng.core'; @@ -135,16 +136,16 @@ import { ActivationEnd, ChildActivationEnd } from '@angular/router'; @Injectable() class SomeService { + private routerEvents = inject(RouterEvents); + moduleActivation$ = this.routerEvents.getEvents(ActivationEnd, ChildActivationEnd); /* Observable */ - - constructor(private routerEvents: RouterEvents) {} } ``` ### How to Get All Router Events -You can use `getEvents` to get a stream of all router events without passing any event constructors. This is nothing different from accessing `events` property of `Router` and is added to the service just for convenience. +You can use `getEvents` to get a stream of all router events without passing any event classes. This is nothing different from accessing `events` property of `Router` and is added to the service just for convenience. ```js import { RouterEvents } from '@abp/ng.core'; @@ -152,9 +153,9 @@ import { ActivationEnd, ChildActivationEnd } from '@angular/router'; @Injectable() class SomeService { + private routerEvents = inject(RouterEvents); + routerEvent$ = this.routerEvents.getAllEvents(); /* Observable */ - - constructor(private routerEvents: RouterEvents) {} } ``` diff --git a/docs/en/framework/ui/angular/service-proxies.md b/docs/en/framework/ui/angular/service-proxies.md index 695e3027c4..23e17b9759 100644 --- a/docs/en/framework/ui/angular/service-proxies.md +++ b/docs/en/framework/ui/angular/service-proxies.md @@ -89,14 +89,15 @@ The `generate-proxy` command generates one service per back-end controller and a A variable named `apiName` (available as of v2.4) is defined in each service. `apiName` matches the module's `RemoteServiceName`. This variable passes to the `RestService` as a parameter at each request. If there is no microservice API defined in the environment, `RestService` uses the default. See [getting a specific API endpoint from application config](./http-requests#how-to-get-a-specific-api-endpoint-from-application-config) -The `providedIn` property of the services is defined as `'root'`. Therefore there is no need to provide them in a module. You can use them directly by injecting them into the constructor as shown below: +The `providedIn` property of the services is defined as `'root'`. Therefore there is no need to provide them in a module. You can use them directly by injecting as shown below: ```js import { BookService } from '@proxy/books'; +import { inject } from '@angular/core'; @Component(/* component metadata here */) export class BookComponent implements OnInit { - constructor(private service: BookService) {} + private service = inject(BookService); ngOnInit() { this.service.get().subscribe( diff --git a/docs/en/framework/ui/angular/settings.md b/docs/en/framework/ui/angular/settings.md index f81bc1594c..f6325c9a8d 100644 --- a/docs/en/framework/ui/angular/settings.md +++ b/docs/en/framework/ui/angular/settings.md @@ -10,12 +10,13 @@ To use the `ConfigStateService`, you must inject it in your class as a dependenc ```js import { ConfigStateService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private config: ConfigStateService) {} + private config = inject(ConfigStateService); } ``` diff --git a/docs/en/framework/ui/angular/subscription-service.md b/docs/en/framework/ui/angular/subscription-service.md index e080f8f3fa..f098d556d4 100644 --- a/docs/en/framework/ui/angular/subscription-service.md +++ b/docs/en/framework/ui/angular/subscription-service.md @@ -8,6 +8,7 @@ You have to provide the `SubscriptionService` at component or directive level, b ```js import { SubscriptionService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ @@ -16,7 +17,9 @@ import { SubscriptionService } from '@abp/ng.core'; class DemoComponent { count$ = interval(1000); - constructor(private subscription: SubscriptionService) { + private subscription = inject(SubscriptionService); + + constructor() { this.subscription.addOne(this.count$, console.log); } } @@ -38,7 +41,7 @@ You can pass a `next` function and an `error` function. providers: [SubscriptionService], }) class DemoComponent implements OnInit { - constructor(private subscription: SubscriptionService) {} + private subscription = inject(SubscriptionService); ngOnInit() { const source$ = interval(1000); @@ -61,7 +64,7 @@ Or, you can pass an observer. providers: [SubscriptionService], }) class DemoComponent implements OnInit { - constructor(private subscription: SubscriptionService) {} + private subscription = inject(SubscriptionService); ngOnInit() { const source$ = interval(1000); @@ -87,7 +90,7 @@ There are two ways to do that. If you are not going to subscribe again, you may providers: [SubscriptionService], }) class DemoComponent implements OnInit { - constructor(private subscription: SubscriptionService) {} + private subscription = inject(SubscriptionService); ngOnInit() { this.subscription.addOne(interval(1000), console.log); @@ -107,7 +110,7 @@ This will clear all subscriptions, but you will not be able to subscribe again. providers: [SubscriptionService], }) class DemoComponent implements OnInit { - constructor(private subscription: SubscriptionService) {} + private subscription = inject(SubscriptionService); ngOnInit() { this.subscription.addOne(interval(1000), console.log); @@ -131,8 +134,7 @@ Sometimes, you may need to unsubscribe from a particular subscription but leave }) class DemoComponent implements OnInit { countSubscription: Subscription; - - constructor(private subscription: SubscriptionService) {} + private subscription = inject(SubscriptionService); ngOnInit() { this.countSubscription = this.subscription.addOne( @@ -159,8 +161,7 @@ You may want to take control of a particular subscription. In such a case, you m }) class DemoComponent implements OnInit { countSubscription: Subscription; - - constructor(private subscription: SubscriptionService) {} + private subscription = inject(SubscriptionService); ngOnInit() { this.countSubscription = this.subscription.addOne( @@ -186,7 +187,7 @@ Please use `isClosed` getter to check if `closeAll` was called before. providers: [SubscriptionService], }) class DemoComponent implements OnInit { - constructor(private subscription: SubscriptionService) {} + private subscription = inject(SubscriptionService); ngOnInit() { this.subscription.addOne(interval(1000), console.log); diff --git a/docs/en/framework/ui/angular/theming.md b/docs/en/framework/ui/angular/theming.md index 1940fc331b..b19f713c71 100644 --- a/docs/en/framework/ui/angular/theming.md +++ b/docs/en/framework/ui/angular/theming.md @@ -105,12 +105,14 @@ The [Application Startup Template](../../../solution-templates/application-modul ```ts import { RoutesService, eLayoutType } from '@abp/ng.core'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; @Component(/* component metadata */) export class AppComponent { - constructor(routes: RoutesService) { - routes.add([ + private routes = inject(RoutesService); + + constructor() { + this.routes.add([ { path: '/your-path', name: 'Your navigation', @@ -141,7 +143,7 @@ See the [Modifying the Menu](modifying-the-menu.md) document to learn more about ````ts import { NavItemsService } from '@abp/ng.theme.shared'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; @Component({ template: ` @@ -153,8 +155,10 @@ export class MySearchInputComponent {} @Component(/* component metadata */) export class AppComponent { - constructor(private navItems: NavItemsService) { - navItems.addItems([ + private navItems = inject(NavItemsService); + + constructor() { + this.navItems.addItems([ { id: 'MySearchInput', order: 1, @@ -184,25 +188,25 @@ Language Selection toolbar item is generally a dropdown that is used to switch b **Example: Get the currently selected language** ````ts -import {SessionStateService} from '@abp/ng.core'; +import { SessionStateService } from '@abp/ng.core'; +import { inject } from '@angular/core'; //... -constructor(private sessionState: SessionStateService) { - const lang = this.sessionState.getLanguage() -} +const sessionState = inject(SessionStateService); +const lang = sessionState.getLanguage(); ```` **Example: Set the selected language** ````ts -import {SessionStateService} from '@abp/ng.core'; +import { SessionStateService } from '@abp/ng.core'; +import { inject } from '@angular/core'; //... -constructor(private sessionState: SessionStateService) { - const lang = this.sessionState.setLanguage('en') -} +const sessionState = inject(SessionStateService); +sessionState.setLanguage('en'); ```` @@ -219,7 +223,7 @@ All of the options are shown below. You can choose either of them. ````ts import { eUserMenuItems } from '@abp/ng.theme.basic'; import { UserMenuService } from '@abp/ng.theme.shared'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { Router } from '@angular/router'; // make sure that you import this component in a NgModule @@ -234,20 +238,23 @@ import { Router } from '@angular/router'; }) export class UserMenuItemComponent { // you can inject the data through `INJECTOR_PIPE_DATA_TOKEN` token - constructor(@Inject(INJECTOR_PIPE_DATA_TOKEN) public data: UserMenu) {} + public data = inject(INJECTOR_PIPE_DATA_TOKEN); } @Component({/* component metadata */}) export class AppComponent { - constructor(private userMenu: UserMenuService, private router: Router) { + private userMenu = inject(UserMenuService); + private router = inject(Router); + + constructor() { this.userMenu.addItems([ { id: 'UserMenu.MyAccount', order: 1, - + // HTML example html: `My account`, - + // text template example textTemplate: { text: 'AbpAccount::MyAccount', diff --git a/docs/en/framework/ui/angular/toaster-service.md b/docs/en/framework/ui/angular/toaster-service.md index a6c65ccb72..2737e1067e 100644 --- a/docs/en/framework/ui/angular/toaster-service.md +++ b/docs/en/framework/ui/angular/toaster-service.md @@ -8,12 +8,13 @@ You do not have to provide the `ToasterService` at component level, because it i ```js import { ToasterService } from '@abp/ng.theme.shared'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ }) class DemoComponent { - constructor(private toaster: ToasterService) {} + private toaster = inject(ToasterService); } ``` @@ -36,22 +37,23 @@ Options can be passed as the third parameter to `success`, `warn`, `error`, and ```js import { Toaster, ToasterService } from '@abp/ng.theme.shared'; -//... +import { inject } from '@angular/core'; -constructor(private toaster: ToasterService) {} +// inside the class +private toaster = inject(ToasterService); //... const options: Partial = { - life: 10000, - sticky: false, - closable: true, - tapToDismiss: true, - messageLocalizationParams: ['Demo', '1'], - titleLocalizationParams: [], - iconClass: 'custom-icon-name'; - }; - - this.toaster.error('AbpUi::EntityNotFoundErrorMessage', 'AbpUi::Error', options); + life: 10000, + sticky: false, + closable: true, + tapToDismiss: true, + messageLocalizationParams: ['Demo', '1'], + titleLocalizationParams: [], + iconClass: 'custom-icon-name' +}; + +this.toaster.error('AbpUi::EntityNotFoundErrorMessage', 'AbpUi::Error', options); ``` - `life` option is the closing time in milliseconds. Default value is `5000`. @@ -93,15 +95,16 @@ If you want the ABP to utilize 3rd party libraries for the toasters instead of t ```js // your-custom-toaster.service.ts -import { Injectable } from '@angular/core'; +import { Injectable, inject } from '@angular/core'; import { Config, LocalizationService } from '@abp/ng.core'; import { Toaster } from '@abp/ng.theme.shared'; import { ToastrService } from 'ngx-toastr'; @Injectable() export class CustomToasterService implements Toaster.Service { - constructor(private toastr: ToastrService, private localizationService: LocalizationService) {} - + private toastr = inject(ToastrService); + private localizationService = inject(LocalizationService) + error( message: Config.LocalizationParam, title?: Config.LocalizationParam, diff --git a/docs/en/framework/ui/angular/track-by-service.md b/docs/en/framework/ui/angular/track-by-service.md index a7df7b80b6..84159f12de 100644 --- a/docs/en/framework/ui/angular/track-by-service.md +++ b/docs/en/framework/ui/angular/track-by-service.md @@ -10,6 +10,7 @@ You do not have to provide the `TrackByService` at module or component level, be ```js import { TrackByService } from '@abp/ng.core'; +import { inject } from '@angular/core'; @Component({ /* class metadata here */ @@ -17,7 +18,7 @@ import { TrackByService } from '@abp/ng.core'; class DemoComponent { list: Item[]; - constructor(public readonly track: TrackByService) {} + public readonly track = inject(TrackByService); } ``` diff --git a/docs/en/modules/setting-management.md b/docs/en/modules/setting-management.md index 842233e8b4..7772e7f1f5 100644 --- a/docs/en/modules/setting-management.md +++ b/docs/en/modules/setting-management.md @@ -289,16 +289,18 @@ yarn ng generate component my-settings Open the `app.component.ts` and modify the file as shown below: ```js -import { Component } from '@angular/core'; -import { SettingTabsService } from '@abp/ng.setting-management/config'; // imported SettingTabsService -import { MySettingsComponent } from './my-settings/my-settings.component'; // imported MySettingsComponent +import { Component, inject } from '@angular/core'; +import { SettingTabsService } from '@abp/ng.setting-management/config'; +import { MySettingsComponent } from './my-settings/my-settings.component'; -@Component(/* component metadata */) +@Component({ + // component metadata +}) export class AppComponent { - constructor(private settingTabs: SettingTabsService) // injected MySettingsComponent - { - // added below - settingTabs.add([ + private readonly settingTabs = inject(SettingTabsService); + + constructor() { + this.settingTabs.add([ { name: 'MySettings', order: 1, diff --git a/docs/en/tutorials/book-store/part-02.md b/docs/en/tutorials/book-store/part-02.md index 43fcb55d47..e0a869c79f 100644 --- a/docs/en/tutorials/book-store/part-02.md +++ b/docs/en/tutorials/book-store/part-02.md @@ -446,7 +446,7 @@ Open the `/src/app/book/book.component.ts` file and replace the content as below ```js import { ListService, PagedResultDto } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { BookService, BookDto } from '@proxy/books'; @Component({ @@ -458,7 +458,8 @@ import { BookService, BookDto } from '@proxy/books'; export class BookComponent implements OnInit { book = { items: [], totalCount: 0 } as PagedResultDto; - constructor(public readonly list: ListService, private bookService: BookService) {} + public readonly list = inject(ListService); + private readonly bookService = inject(BookService); ngOnInit() { const bookStreamCreator = (query) => this.bookService.getList(query); diff --git a/docs/en/tutorials/book-store/part-03.md b/docs/en/tutorials/book-store/part-03.md index e67353b1fa..ae96f8a8e0 100644 --- a/docs/en/tutorials/book-store/part-03.md +++ b/docs/en/tutorials/book-store/part-03.md @@ -576,7 +576,7 @@ Open `/src/app/book/book.component.ts` and replace the content as below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { BookService, BookDto } from '@proxy/books'; @Component({ @@ -588,9 +588,10 @@ import { BookService, BookDto } from '@proxy/books'; export class BookComponent implements OnInit { book = { items: [], totalCount: 0 } as PagedResultDto; - isModalOpen = false; // add this line + isModalOpen = false; - constructor(public readonly list: ListService, private bookService: BookService) {} + public readonly list = inject(ListService); + private readonly bookService = inject(BookService); ngOnInit() { const bookStreamCreator = (query) => this.bookService.getList(query); @@ -600,7 +601,7 @@ export class BookComponent implements OnInit { }); } - // add new method + //add new method createBook() { this.isModalOpen = true; } @@ -668,7 +669,7 @@ Open `/src/app/book/book.component.ts` and replace the content as below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { BookService, BookDto, bookTypeOptions } from '@proxy/books'; // add bookTypeOptions import { FormGroup, FormBuilder, Validators } from '@angular/forms'; // add this @@ -688,11 +689,9 @@ export class BookComponent implements OnInit { isModalOpen = false; - constructor( - public readonly list: ListService, - private bookService: BookService, - private fb: FormBuilder // inject FormBuilder - ) {} + public readonly list = inject(ListService); + private readonly bookService = inject(BookService); + private readonly fb = inject(FormBuilder); // inject FormBuilder ngOnInit() { const bookStreamCreator = (query) => this.bookService.getList(query); @@ -702,6 +701,7 @@ export class BookComponent implements OnInit { }); } + // add new method createBook() { this.buildForm(); // add this line this.isModalOpen = true; @@ -735,7 +735,7 @@ export class BookComponent implements OnInit { * Imported `FormGroup`, `FormBuilder` and `Validators` from `@angular/forms`. * Added a `form: FormGroup` property. * Added a `bookTypes` property as a list of `BookType` enum members. That will be used in form options. -* Injected `FormBuilder` into the constructor. [FormBuilder](https://angular.io/api/forms/FormBuilder) provides convenient methods for generating form controls. It reduces the amount of boilerplate needed to build complex forms. +* Injected with the `FormBuilder` inject function.. [FormBuilder](https://angular.io/api/forms/FormBuilder) provides convenient methods for generating form controls. It reduces the amount of boilerplate needed to build complex forms. * Added a `buildForm` method to the end of the file and executed the `buildForm()` in the `createBook` method. * Added a `save` method. @@ -823,7 +823,7 @@ Open `/src/app/book/book.component.ts` and replace the content as below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { BookService, BookDto, bookTypeOptions } from '@proxy/books'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; @@ -848,11 +848,9 @@ export class BookComponent implements OnInit { isModalOpen = false; - constructor( - public readonly list: ListService, - private bookService: BookService, - private fb: FormBuilder - ) {} + public readonly list = inject(ListService); + private readonly bookService = inject(BookService); + private readonly fb = inject(FormBuilder); ngOnInit() { const bookStreamCreator = (query) => this.bookService.getList(query); @@ -903,7 +901,7 @@ Open `/src/app/book/book.component.ts` and replace the content as shown below: ```js import { ListService, PagedResultDto } from '@abp/ng.core'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { BookService, BookDto, bookTypeOptions } from '@proxy/books'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; import { NgbDateNativeAdapter, NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap'; @@ -925,11 +923,9 @@ export class BookComponent implements OnInit { isModalOpen = false; - constructor( - public readonly list: ListService, - private bookService: BookService, - private fb: FormBuilder - ) {} + public readonly list = inject(ListService); + private readonly bookService = inject(BookService); + private readonly fb = inject(FormBuilder); ngOnInit() { const bookStreamCreator = (query) => this.bookService.getList(query); @@ -1039,34 +1035,40 @@ This template will show the **Edit** text for edit record operation, **New Book* Open the `/src/app/book/book.component.ts` file and inject the `ConfirmationService`. -Replace the constructor as below: +Replace the injected services as below: ```js // ... // add new imports import { ConfirmationService, Confirmation } from '@abp/ng.theme.shared'; +import { Component, OnInit, inject } from '@angular/core'; -//change the constructor -constructor( - public readonly list: ListService, - private bookService: BookService, - private fb: FormBuilder, - private confirmation: ConfirmationService // inject the ConfirmationService -) {} - -// Add a delete method -delete(id: string) { - this.confirmation.warn('::AreYouSureToDelete', '::AreYouSure').subscribe((status) => { - if (status === Confirmation.Status.confirm) { - this.bookService.delete(id).subscribe(() => this.list.get()); - } - }); +// ... + +export class BookComponent implements OnInit { + // ... + + public readonly list = inject(ListService); + private readonly bookService = inject(BookService); + private readonly fb = inject(FormBuilder); + private readonly confirmation = inject(ConfirmationService); // inject the ConfirmationService + + // ... + + // Add a delete method + delete(id: string) { + this.confirmation.warn('::AreYouSureToDelete', '::AreYouSure').subscribe((status) => { + if (status === Confirmation.Status.confirm) { + this.bookService.delete(id).subscribe(() => this.list.get()); + } + }); + } } ``` * We imported `ConfirmationService`. -* We injected `ConfirmationService` to the constructor. +* We injected `ConfirmationService` using the `inject()` function. * Added a `delete` method. > Check out the [Confirmation Popup documentation](../../framework/ui/angular/confirmation-service.md) for more about this service. diff --git a/docs/en/tutorials/book-store/part-09.md b/docs/en/tutorials/book-store/part-09.md index 18ecd2726d..95de6ccd61 100644 --- a/docs/en/tutorials/book-store/part-09.md +++ b/docs/en/tutorials/book-store/part-09.md @@ -601,7 +601,7 @@ This command generates the service proxy for the author service and the related Open the `/src/app/author/author.component.ts` file and replace the content as below: ```js -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { ListService, PagedResultDto } from '@abp/ng.core'; import { AuthorService, AuthorDto } from '@proxy/authors'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; @@ -623,12 +623,10 @@ export class AuthorComponent implements OnInit { selectedAuthor = {} as AuthorDto; - constructor( - public readonly list: ListService, - private authorService: AuthorService, - private fb: FormBuilder, - private confirmation: ConfirmationService - ) {} + public readonly list = inject(ListService); + private readonly authorService = inject(AuthorService); + private readonly fb = inject(FormBuilder); + private readonly confirmation = inject(ConfirmationService); ngOnInit(): void { const authorStreamCreator = (query) => this.authorService.getList(query); diff --git a/docs/en/tutorials/book-store/part-10.md b/docs/en/tutorials/book-store/part-10.md index 02d1f81aba..ccb6755468 100644 --- a/docs/en/tutorials/book-store/part-10.md +++ b/docs/en/tutorials/book-store/part-10.md @@ -1009,12 +1009,12 @@ export class BookComponent implements OnInit { isModalOpen = false; - constructor( - public readonly list: ListService, - private bookService: BookService, - private fb: FormBuilder, - private confirmation: ConfirmationService - ) { + public readonly list = inject(ListService); + private readonly bookService = inject(BookService); + private readonly fb = inject(FormBuilder); + private readonly confirmation = inject(ConfirmationService); + + constructor() { this.authors$ = bookService.getAuthorLookup().pipe(map((r) => r.items)); } diff --git a/docs/en/tutorials/microservice/part-05.md b/docs/en/tutorials/microservice/part-05.md index e72e94fc66..26bd3e3306 100644 --- a/docs/en/tutorials/microservice/part-05.md +++ b/docs/en/tutorials/microservice/part-05.md @@ -643,7 +643,7 @@ export const ORDER_SERVICE_ROUTES: Routes = [ * Create `order.component.ts` file under the `projects/ordering-service/src/lib/order` folder as following code: ```typescript -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { CommonModule } from '@angular/common'; import { OrderDto, OrderService } from './proxy/ordering-service/services'; @@ -657,12 +657,13 @@ export class OrderComponent { items: OrderDto[] = []; - constructor(private readonly proxy: OrderService) { + private readonly proxy = inject(OrderService); + + constructor() { this.proxy.getList().subscribe((res) => { this.items = res; }); } - } ``` diff --git a/docs/en/tutorials/todo/layered/index.md b/docs/en/tutorials/todo/layered/index.md index e2279e3d57..b990704c7a 100644 --- a/docs/en/tutorials/todo/layered/index.md +++ b/docs/en/tutorials/todo/layered/index.md @@ -751,7 +751,7 @@ Open the `/angular/src/app/home/home.component.ts` file and replace its content ```js import { ToasterService } from '@abp/ng.theme.shared'; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { TodoItemDto, TodoService } from '@proxy'; @Component({ @@ -764,10 +764,8 @@ export class HomeComponent implements OnInit { todoItems: TodoItemDto[]; newTodoText: string; - constructor( - private todoService: TodoService, - private toasterService: ToasterService) - { } + private readonly todoService = inject(TodoService); + private readonly toasterService = inject(ToasterService); ngOnInit(): void { this.todoService.getList().subscribe(response => { @@ -775,7 +773,7 @@ export class HomeComponent implements OnInit { }); } - create(): void{ + create(): void { this.todoService.create(this.newTodoText).subscribe((result) => { this.todoItems = this.todoItems.concat(result); this.newTodoText = null; @@ -789,7 +787,6 @@ export class HomeComponent implements OnInit { }); } } - ``` We've used `todoService` to get the list of todo items and assigned the returning value to the `todoItems` array. We've also added `create` and `delete` methods. These methods will be used on the view side. diff --git a/docs/en/tutorials/todo/single-layer/index.md b/docs/en/tutorials/todo/single-layer/index.md index 2ca25ea36d..a823e91dc0 100644 --- a/docs/en/tutorials/todo/single-layer/index.md +++ b/docs/en/tutorials/todo/single-layer/index.md @@ -718,7 +718,7 @@ Open the `/angular/src/app/home/home.component.ts` file and replace its content ```ts import { ToasterService } from "@abp/ng.theme.shared"; -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, inject } from '@angular/core'; import { TodoItemDto } from "@proxy/services/dtos"; import { TodoService } from "@proxy/services"; @@ -727,16 +727,13 @@ import { TodoService } from "@proxy/services"; templateUrl: './home.component.html', styleUrls: ['./home.component.scss'], }) - export class HomeComponent implements OnInit { todoItems: TodoItemDto[]; newTodoText: string; - constructor( - private todoService: TodoService, - private toasterService: ToasterService) - { } + private readonly todoService = inject(TodoService); + private readonly toasterService = inject(ToasterService); ngOnInit(): void { this.todoService.getList().subscribe(response => { @@ -744,7 +741,7 @@ export class HomeComponent implements OnInit { }); } - create(): void{ + create(): void { this.todoService.create(this.newTodoText).subscribe((result) => { this.todoItems = this.todoItems.concat(result); this.newTodoText = null; diff --git a/docs/en/ui-themes/lepton-x-lite/angular.md b/docs/en/ui-themes/lepton-x-lite/angular.md index 153857385e..4abe6c86ff 100644 --- a/docs/en/ui-themes/lepton-x-lite/angular.md +++ b/docs/en/ui-themes/lepton-x-lite/angular.md @@ -131,15 +131,16 @@ The **Layout components** and all the replacable components are predefined in `e ```js import { ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService import { eIdentityComponents } from '@abp/ng.identity'; // imported eIdentityComponents enum -import { eThemeLeptonXComponents } from '@abp/ng.theme.lepton-x'; // imported eThemeLeptonXComponents enum +import { eThemeLeptonXComponents } from '@abp/ng.theme.lepton-x'; // imported eThemeLeptonXComponents enum +import { Component, inject } from '@angular/core'; //... @Component(/* component metadata */) export class AppComponent { - constructor( - private replaceableComponents: ReplaceableComponentsService, // injected the service - ) { + private replaceableComponents = inject(ReplaceableComponentsService); + + constructor() { this.replaceableComponents.add({ component: YourNewApplicationLayoutComponent, key: eThemeLeptonXComponents.ApplicationLayout, diff --git a/docs/en/ui-themes/lepton-x/angular-customization.md b/docs/en/ui-themes/lepton-x/angular-customization.md index 71ee3761f2..4189ed6cba 100644 --- a/docs/en/ui-themes/lepton-x/angular-customization.md +++ b/docs/en/ui-themes/lepton-x/angular-customization.md @@ -18,14 +18,18 @@ The **Layout components** and all the replacable components are predefined in `e ### How to replace a component ```js -import { ReplaceableComponentsService } from '@abp/ng.core'; // imported ReplaceableComponentsService -import {eThemeLeptonXComponents} from "@volosoft/abp.ng.theme.lepton-x"; // imported eThemeLeptonXComponents enum -//... -@Component(/* component metadata */) +import { Component, inject } from '@angular/core'; +import { ReplaceableComponentsService } from '@abp/ng.core'; +import { eThemeLeptonXComponents } from '@volosoft/abp.ng.theme.lepton-x'; +import { YourNewApplicationLayoutComponent } from './your-new-application-layout.component'; // varsa + +@Component({ + // component metadata +}) export class AppComponent { - constructor( - private replaceableComponents: ReplaceableComponentsService, // injected the service - ) { + private readonly replaceableComponents = inject(ReplaceableComponentsService); + + constructor() { this.replaceableComponents.add({ component: YourNewApplicationLayoutComponent, key: eThemeLeptonXComponents.ApplicationLayout,