From 9c1855624116b5778f26ab9cc9562028de1cfa1c Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 15:20:14 +0300 Subject: [PATCH 01/31] Update Angular environment service injection example Revised the example to use the inject() function for EnvironmentService in Angular, reflecting modern dependency injection practices. --- docs/en/framework/ui/angular/environment.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/en/framework/ui/angular/environment.md b/docs/en/framework/ui/angular/environment.md index 7fd1b1273a..68fa516d49 100644 --- a/docs/en/framework/ui/angular/environment.md +++ b/docs/en/framework/ui/angular/environment.md @@ -126,13 +126,14 @@ import { environment } from '../environments/environment'; 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 */ }) class DemoComponent { - constructor(private environment: EnvironmentService) {} + private environment = inject(EnvironmentService); } ``` From dbc82fa41331152349dd89c4ecf94fd8b58da813 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 15:22:22 +0300 Subject: [PATCH 02/31] Update Angular service injection example Replaces constructor-based injection with the inject() function in the Angular service usage example. Updates the explanation to reflect this change for improved clarity and alignment with modern Angular practices. --- docs/en/framework/ui/angular/service-proxies.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/en/framework/ui/angular/service-proxies.md b/docs/en/framework/ui/angular/service-proxies.md index 695e3027c4..736a9ffa73 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 them 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( From 218e11ebfe1fe8806b7b9f065e8eb1827e539116 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 15:27:10 +0300 Subject: [PATCH 03/31] Update config-state-service.md --- docs/en/framework/ui/angular/config-state-service.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/en/framework/ui/angular/config-state-service.md b/docs/en/framework/ui/angular/config-state-service.md index f5415d38b3..14e370fe6f 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 { - constructor(private config: ConfigStateService) {} + private config = inject(ConfigStateService); } ``` @@ -121,8 +122,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'; -constructor(private abpApplicationConfigurationService: AbpApplicationConfigurationService, private config: ConfigStateService) { +private abpApplicationConfigurationService = inject(AbpApplicationConfigurationService); +private config = inject(ConfigStateService); + +constructor() { this.abpApplicationConfigurationService.get({ includeLocalizationResources: false }).subscribe(config => { this.config.setState(config); }) From b8261a62a1d055cd0ba7e2ce37fe3b231167773c Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 15:28:26 +0300 Subject: [PATCH 04/31] Update http-requests.md --- docs/en/framework/ui/angular/http-requests.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); } ``` From 37b0a787515cd0000c87da2ea13e4d558740602e Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 15:29:49 +0300 Subject: [PATCH 05/31] Update localization.md --- docs/en/framework/ui/angular/localization.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/en/framework/ui/angular/localization.md b/docs/en/framework/ui/angular/localization.md index 4ff0744212..69d976be87 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); } ``` From 65c3af1ce5c066c5cfb80048b65cb0c54301b6a9 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 15:30:59 +0300 Subject: [PATCH 06/31] Update settings.md --- docs/en/framework/ui/angular/settings.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); } ``` From 81ccc46660c6ecfc7bcf1743eae39005b77b5b0e Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 15:32:48 +0300 Subject: [PATCH 07/31] Update features.md --- docs/en/framework/ui/angular/features.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); } ``` From da5d56aef1a0a1e575faa8b91ca59e60ef17617b Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:30:23 +0300 Subject: [PATCH 08/31] Update global-features.md --- docs/en/framework/ui/angular/global-features.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 { } } - From 8c4f154e921c8ce812b130ce015e08f132ec55f3 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:32:29 +0300 Subject: [PATCH 09/31] Update permission-management.md --- docs/en/framework/ui/angular/permission-management.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/en/framework/ui/angular/permission-management.md b/docs/en/framework/ui/angular/permission-management.md index c797402003..d7ae48ec07 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 From a2302c1b627fa5f5ee1492d7393115ebf55d6591 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:37:31 +0300 Subject: [PATCH 10/31] Update subscription-service.md --- .../ui/angular/subscription-service.md | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) 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); From 4b1358bf062ff83efb2fb26c59a064c6f22e1ce0 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:39:55 +0300 Subject: [PATCH 11/31] Update list-service.md --- docs/en/framework/ui/angular/list-service.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/en/framework/ui/angular/list-service.md b/docs/en/framework/ui/angular/list-service.md index e657cdab1b..e735655959 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: From ffd36c70ca4da66b15d5a24dadc2216f682e88ab Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:48:06 +0300 Subject: [PATCH 12/31] Update track-by-service.md --- docs/en/framework/ui/angular/track-by-service.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); } ``` From 1107fac5881f5fc5bd642b711d4c8d2377d7f7cc Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:50:44 +0300 Subject: [PATCH 13/31] Update dom-insertion-service.md --- .../framework/ui/angular/dom-insertion-service.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) 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;}') From 78aeba1d70cc310a161d0a40a7121d3f2517c610 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:53:46 +0300 Subject: [PATCH 14/31] Update lazy-load-service.md --- .../framework/ui/angular/lazy-load-service.md | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) 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) {} } ``` From 87ef71e53ac513a375f079743ccefc77d521eeec Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:54:57 +0300 Subject: [PATCH 15/31] Update content-projection-service.md --- docs/en/framework/ui/angular/content-projection-service.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); } ``` From 8250c4630a1fb2e9e986b0ca387ec8d60adb30c1 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:56:10 +0300 Subject: [PATCH 16/31] Update modal.md --- docs/en/framework/ui/angular/modal.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/en/framework/ui/angular/modal.md b/docs/en/framework/ui/angular/modal.md index 2b8412202c..8c8efc2caf 100644 --- a/docs/en/framework/ui/angular/modal.md +++ b/docs/en/framework/ui/angular/modal.md @@ -133,10 +133,14 @@ 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 { - form = this.fb.group({ + private fb = inject(FormBuilder); + private service = inject(BookService); + + form = this.fb.group({ author: [null, [Validators.required]], name: [null, [Validators.required]], price: [null, [Validators.required, Validators.min(0)]], @@ -145,11 +149,8 @@ export class BookComponent { }); inProgress: boolean; - isModalOpen: boolean; - constructor(private fb: FormBuilder, private service: BookService) {} - save() { if (this.form.invalid) return; From 2f95ee5e7eb9b0166d036c8c862dbac33818cd9a Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 17:57:22 +0300 Subject: [PATCH 17/31] Update confirmation-service.md --- docs/en/framework/ui/angular/confirmation-service.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/en/framework/ui/angular/confirmation-service.md b/docs/en/framework/ui/angular/confirmation-service.md index c1d2dee850..5cafb9c700 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 module or component leve ```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) {} +// Sınıf içinde: +private confirmation = inject(ConfirmationService); this.confirmation .warn('::WillBeDeleted', { key: '::AreYouSure', defaultValue: 'Are you sure?' }) From ea56152eb69d687293af1fd8e6d1115ea68ad02f Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 18:01:36 +0300 Subject: [PATCH 18/31] Update toaster-service.md --- .../framework/ui/angular/toaster-service.md | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/docs/en/framework/ui/angular/toaster-service.md b/docs/en/framework/ui/angular/toaster-service.md index ad08697eeb..4c5246904f 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 module or component level, be ```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) {} +// Sınıf içinde: +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, From a7ff21508cb6444d747d9b1c86eb39f043f92f06 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 18:02:33 +0300 Subject: [PATCH 19/31] Update page-alerts.md --- docs/en/framework/ui/angular/page-alerts.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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({ From cc97483723cdcec958b01ae89ebf2402c7fcfba0 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 18:07:03 +0300 Subject: [PATCH 20/31] Update abp-window-service.md --- docs/en/framework/ui/angular/abp-window-service.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/framework/ui/angular/abp-window-service.md b/docs/en/framework/ui/angular/abp-window-service.md index bc060f79b5..56bae7896c 100644 --- a/docs/en/framework/ui/angular/abp-window-service.md +++ b/docs/en/framework/ui/angular/abp-window-service.md @@ -14,9 +14,9 @@ Firstly, ensure that the service is injected into the component or any other Ang ```js import { AbpWindowService } from '@abp/ng.core'; -constructor(private abpWindowService: AbpWindowService) { } +private abpWindowService = inject(AbpWindowService) // or -// private abpWindowService = inject(AbpWindowService) +// constructor(private abpWindowService: AbpWindowService) { } ``` ### Downloading a Blob From 9c2a5606fb56a2218d326b868c1c87e5f503c0fa Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 18:12:31 +0300 Subject: [PATCH 21/31] Update theming.md --- docs/en/framework/ui/angular/theming.md | 42 +++++++++++++++---------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/docs/en/framework/ui/angular/theming.md b/docs/en/framework/ui/angular/theming.md index 1940fc331b..177d87c382 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,24 +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 +224,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, Inject } from '@angular/core'; import { Router } from '@angular/router'; // make sure that you import this component in a NgModule @@ -239,15 +244,18 @@ export class UserMenuItemComponent { @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', From 53149ef2845f4df5683ade00c6afe170c9bb6b1f Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 18:13:38 +0300 Subject: [PATCH 22/31] Update angular.md --- docs/en/ui-themes/lepton-x-lite/angular.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/en/ui-themes/lepton-x-lite/angular.md b/docs/en/ui-themes/lepton-x-lite/angular.md index 430bc2ee73..88fd0627b6 100644 --- a/docs/en/ui-themes/lepton-x-lite/angular.md +++ b/docs/en/ui-themes/lepton-x-lite/angular.md @@ -106,15 +106,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, From af48837fb6a8ff34c736e5f49cc5a85b034c9d68 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 18:17:13 +0300 Subject: [PATCH 23/31] Update modifying-the-menu.md --- .../ui/angular/modifying-the-menu.md | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/docs/en/framework/ui/angular/modifying-the-menu.md b/docs/en/framework/ui/angular/modifying-the-menu.md index ef5e12782f..d8e56a3bd6 100644 --- a/docs/en/framework/ui/angular/modifying-the-menu.md +++ b/docs/en/framework/ui/angular/modifying-the-menu.md @@ -28,12 +28,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', @@ -119,15 +121,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$; } ``` @@ -160,12 +163,14 @@ export class AppModule {} ```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); } } ``` @@ -289,7 +294,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: ` @@ -301,8 +306,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, @@ -331,13 +338,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); } } ``` From 08c864b3f33a787741258d8f7802cf7336412fdc Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 18:27:41 +0300 Subject: [PATCH 24/31] Update component-replacement.md --- .../ui/angular/component-replacement.md | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/docs/en/framework/ui/angular/component-replacement.md b/docs/en/framework/ui/angular/component-replacement.md index aa9f66df1b..20fe50e426 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, @@ -257,15 +259,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, + }); } } ``` @@ -445,15 +447,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, + }); } } ``` @@ -483,7 +485,7 @@ import { NAVIGATE_TO_MANAGE_PROFILE, SessionStateService, } from '@abp/ng.core'; -import { Component, Inject } from '@angular/core'; +import { Component, inject, Inject } from '@angular/core'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import snq from 'snq'; @@ -493,9 +495,13 @@ import snq from 'snq'; templateUrl: 'nav-items.component.html', }) 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 { @@ -528,13 +534,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); } @@ -665,15 +664,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, + }); } } ``` From 0baa1bb8e9b0d6a1ad7e4fc0aef794fecc2ee20a Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Tue, 8 Jul 2025 18:29:56 +0300 Subject: [PATCH 25/31] Update page-component.md --- docs/en/framework/ui/angular/page-component.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/framework/ui/angular/page-component.md b/docs/en/framework/ui/angular/page-component.md index b9fbc0b0bc..a93ba4f844 100644 --- a/docs/en/framework/ui/angular/page-component.md +++ b/docs/en/framework/ui/angular/page-component.md @@ -159,6 +159,8 @@ export class MyPageRenderStrategy implements PageRenderStrategy { * an async service can be used within. constructor(private service: SomeAsyncService) {} + or + service = inject(SomeAsyncService) shouldRender(type: string) { return this.service.checkTypeAsync(type).pipe(map(val => val.isTrue())); From ccf3e7c2392e7fabdf9ea76fbb61ddfa3869c4c5 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Wed, 9 Jul 2025 08:59:32 +0300 Subject: [PATCH 26/31] Update router-events.md --- docs/en/framework/ui/angular/router-events.md | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) 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) {} } ``` From 5da47ff38b4bf7448192b66b29da726cdc75d0bc Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Thu, 24 Jul 2025 13:10:12 +0300 Subject: [PATCH 27/31] Update Angular docs to use inject() for DI Refactored Angular documentation examples to use the inject() function for dependency injection instead of constructor injection. This aligns the docs with Angular's recommended DI approach and improves code clarity for service and component instantiation. --- ...aceable-components-work-with-extensions.md | 38 ++++++------ .../ui/angular/http-error-reporter-service.md | 13 +++-- ...ission-management-component-replacement.md | 58 +++++-------------- docs/en/framework/ui/angular/theming.md | 4 +- docs/en/modules/setting-management.md | 18 +++--- 5 files changed, 57 insertions(+), 74 deletions(-) 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/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/theming.md b/docs/en/framework/ui/angular/theming.md index 177d87c382..70928bd16a 100644 --- a/docs/en/framework/ui/angular/theming.md +++ b/docs/en/framework/ui/angular/theming.md @@ -224,7 +224,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, inject, Inject } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { Router } from '@angular/router'; // make sure that you import this component in a NgModule @@ -239,7 +239,7 @@ 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 */}) 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, From b0886151ad26cd04a722887c70bf4626ae6239dc Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Thu, 24 Jul 2025 13:29:59 +0300 Subject: [PATCH 28/31] Refactor Angular docs to use inject() for services --- docs/en/tutorials/book-store/part-02.md | 5 +- docs/en/tutorials/book-store/part-03.md | 82 ++++++++++---------- docs/en/tutorials/book-store/part-09.md | 12 ++- docs/en/tutorials/book-store/part-10.md | 12 +-- docs/en/tutorials/microservice/part-05.md | 7 +- docs/en/tutorials/todo/layered/index.md | 11 +-- docs/en/tutorials/todo/single-layer/index.md | 11 +-- 7 files changed, 68 insertions(+), 72 deletions(-) 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 45444ee76f..0c6fed1238 100644 --- a/docs/en/tutorials/book-store/part-03.md +++ b/docs/en/tutorials/book-store/part-03.md @@ -582,7 +582,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({ @@ -594,9 +594,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); @@ -606,7 +607,7 @@ export class BookComponent implements OnInit { }); } - // add new method + //add new method createBook() { this.isModalOpen = true; } @@ -674,7 +675,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 @@ -694,11 +695,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); @@ -708,6 +707,7 @@ export class BookComponent implements OnInit { }); } + // add new method createBook() { this.buildForm(); // add this line this.isModalOpen = true; @@ -741,7 +741,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. @@ -829,7 +829,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'; @@ -854,11 +854,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); @@ -909,7 +907,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'; @@ -931,11 +929,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); @@ -1045,34 +1041,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 06db5f37d9..93d68295c8 100644 --- a/docs/en/tutorials/book-store/part-09.md +++ b/docs/en/tutorials/book-store/part-09.md @@ -619,7 +619,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'; @@ -641,12 +641,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 d4137e3681..990acd9aad 100644 --- a/docs/en/tutorials/book-store/part-10.md +++ b/docs/en/tutorials/book-store/part-10.md @@ -978,12 +978,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 3fcfc9cac8..1aadd92778 100644 --- a/docs/en/tutorials/microservice/part-05.md +++ b/docs/en/tutorials/microservice/part-05.md @@ -590,7 +590,7 @@ export class OrderingServiceConfigModule { * 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 { OrderDto, OrderService } from './proxy/ordering-service/services'; @Component({ @@ -603,12 +603,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 03c06f75c9..783d1d8854 100644 --- a/docs/en/tutorials/todo/layered/index.md +++ b/docs/en/tutorials/todo/layered/index.md @@ -747,7 +747,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({ @@ -760,10 +760,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 => { @@ -771,7 +769,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; @@ -785,7 +783,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; From 7b36c20036117ee85331a0e209ecae34321da284 Mon Sep 17 00:00:00 2001 From: sumeyye Date: Thu, 24 Jul 2025 14:20:08 +0300 Subject: [PATCH 29/31] fix: typos and some comments --- .../ui/angular/confirmation-service.md | 23 +++++++++++-------- .../framework/ui/angular/service-proxies.md | 2 +- docs/en/framework/ui/angular/theming.md | 1 - .../framework/ui/angular/toaster-service.md | 2 +- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/docs/en/framework/ui/angular/confirmation-service.md b/docs/en/framework/ui/angular/confirmation-service.md index 5cafb9c700..f9b71ad21b 100644 --- a/docs/en/framework/ui/angular/confirmation-service.md +++ b/docs/en/framework/ui/angular/confirmation-service.md @@ -39,7 +39,7 @@ You can subscribe to the confirmation closing event like below: import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared'; import { inject } from '@angular/core'; -// Sınıf içinde: +// inside the class: private confirmation = inject(ConfirmationService); this.confirmation @@ -135,18 +135,23 @@ this.confirmation.clear(); You can change icons with the `withConfirmationIcon()` method of `provideAbpThemeShared` function in the app.module.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"; @NgModule({ providers: [ // ... - provideAbpThemeShared(withConfirmationIcon({ - info: 'fa fa-info-circle', - success: 'fa fa-check-circle', - warning: 'fa fa-exclamation-triangle', - error: 'fa fa-times-circle', - default: 'fa fa-question-circle', - })), + provideAbpThemeShared( + withConfirmationIcon({ + info: "fa fa-info-circle", + success: "fa fa-check-circle", + warning: "fa fa-exclamation-triangle", + error: "fa fa-times-circle", + default: "fa fa-question-circle", + }) + ), ], }) export class AppModule {} diff --git a/docs/en/framework/ui/angular/service-proxies.md b/docs/en/framework/ui/angular/service-proxies.md index 736a9ffa73..23e17b9759 100644 --- a/docs/en/framework/ui/angular/service-proxies.md +++ b/docs/en/framework/ui/angular/service-proxies.md @@ -89,7 +89,7 @@ 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 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'; diff --git a/docs/en/framework/ui/angular/theming.md b/docs/en/framework/ui/angular/theming.md index 177d87c382..401b929d14 100644 --- a/docs/en/framework/ui/angular/theming.md +++ b/docs/en/framework/ui/angular/theming.md @@ -207,7 +207,6 @@ import { inject } from '@angular/core'; const sessionState = inject(SessionStateService); sessionState.setLanguage('en'); -} ```` diff --git a/docs/en/framework/ui/angular/toaster-service.md b/docs/en/framework/ui/angular/toaster-service.md index 4c5246904f..41ca75949d 100644 --- a/docs/en/framework/ui/angular/toaster-service.md +++ b/docs/en/framework/ui/angular/toaster-service.md @@ -39,7 +39,7 @@ Options can be passed as the third parameter to `success`, `warn`, `error`, and import { Toaster, ToasterService } from '@abp/ng.theme.shared'; import { inject } from '@angular/core'; -// Sınıf içinde: +// inside the class private toaster = inject(ToasterService); //... From 600a47776c6fa8c78f8dff26803ffbf98d960676 Mon Sep 17 00:00:00 2001 From: Fahri Gedik Date: Thu, 24 Jul 2025 13:32:04 +0300 Subject: [PATCH 30/31] Update Angular component replacement example --- .../lepton-x/angular-customization.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) 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, From 34e386f515563b7381d7c55d76b6e7a74e92648e Mon Sep 17 00:00:00 2001 From: sumeyye Date: Fri, 25 Jul 2025 13:07:50 +0300 Subject: [PATCH 31/31] update: resolve comments to use new injection instead --- docs/en/framework/ui/angular/abp-window-service.md | 5 ++--- docs/en/framework/ui/angular/page-component.md | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/docs/en/framework/ui/angular/abp-window-service.md b/docs/en/framework/ui/angular/abp-window-service.md index 56bae7896c..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'; -private abpWindowService = inject(AbpWindowService) -// or -// constructor(private abpWindowService: AbpWindowService) { } +private abpWindowService = inject(AbpWindowService) ``` ### Downloading a Blob diff --git a/docs/en/framework/ui/angular/page-component.md b/docs/en/framework/ui/angular/page-component.md index a93ba4f844..3c56d3e658 100644 --- a/docs/en/framework/ui/angular/page-component.md +++ b/docs/en/framework/ui/angular/page-component.md @@ -158,8 +158,6 @@ export class MyPageRenderStrategy implements PageRenderStrategy { * shouldRender can also return an Observable which means * an async service can be used within. - constructor(private service: SomeAsyncService) {} - or service = inject(SomeAsyncService) shouldRender(type: string) {