diff --git a/docs/en/framework/ui/angular/component-replacement.md b/docs/en/framework/ui/angular/component-replacement.md index aa9f66df1b..dd0767bebc 100644 --- a/docs/en/framework/ui/angular/component-replacement.md +++ b/docs/en/framework/ui/angular/component-replacement.md @@ -6,7 +6,7 @@ The reason that you **can replace** but **cannot customize** default ABP compone ## How to Replace a Component -Create a new component that you want to use instead of an ABP component. Add that component to `declarations` and `entryComponents` in the `AppModule`. +Create a new component that you want to use instead of an ABP component. Then, open the `app.component.ts` and execute the `add` method of `ReplaceableComponentsService` to replace your component with an ABP component as shown below: @@ -96,8 +96,6 @@ This command will create a new component named `new-layout`. Now, open the new-l This 'router-outlet' will act as a placeholder that Angular dynamically fills based on the current router state. -note: (don't forget: you should add the app in the app.module.ts file) - #### Step 2: Define a Variable for the Layout Component Although this step is optional, it can be useful if you're going to use the layout component's value multiple times. You can define a variable for the layout component like this: @@ -116,33 +114,29 @@ You can use this variable when you need to refer to the layout component. Next, you need to add the new layout component to the `ReplaceableComponentsService`. This service allows you to replace a component with another one dynamically. -You can do this by defining a provider for `APP_INITIALIZER` that uses a factory function. In this function, you inject the `ReplaceableComponentsService` and use its `add` method to add the new layout component. +You can do this by defining a provider for `provideAppInitializer` that uses a factory function. In this function, you inject the `ReplaceableComponentsService` and use its `add` method to add the new layout component. Here's how you can do it: ```javascript export const CUSTOM_LAYOUT_PROVIDERS = [ - { - provide: APP_INITIALIZER, - useFactory: configureLayoutFn, - deps: [ReplaceableComponentsService], - multi: true, - }, + provideAppInitializer(()=>{ + configureLayoutFn(); + }), ]; + function configureLayoutFn() { const service = inject(ReplaceableComponentsService); - return () => { - service.add({ - key: eCustomLayout.component, - component: CustomLayoutComponent, - }); - }; + service.add({ + key: eCustomLayout.component, + component: CustomLayoutComponent, + }); } ``` -In this code, `configureLayoutFn` is a factory function that adds the new layout component to the `ReplaceableComponentsService`. The `APP_INITIALIZER` provider runs this function when the application starts. +In this code, `configureLayoutFn` is a factory function that adds the new layout component to the `ReplaceableComponentsService`. The `provideAppInitializer` provider runs this function when the application starts. -note: (don't forget: you should add the CUSTOM_LAYOUT_PROVIDERS in the app.module.ts file) +note: (don't forget: you should add the CUSTOM_LAYOUT_PROVIDERS in the app.config.ts file) #### Step 4: Define the Application's Dynamic Layouts @@ -154,14 +148,14 @@ You can add the new layout to the existing layouts like this: export const myDynamicLayouts = new Map([...DEFAULT_DYNAMIC_LAYOUTS, [eCustomLayout.key, eCustomLayout.component]]); ``` -#### Step 5: Pass the Dynamic Layouts to the CoreModule +#### Step 5: Pass the Dynamic Layouts to the Core Provider The final step is to pass the dynamic layouts to the `provideAbpCore` using the `withOptions` method. This method allows you to configure the module with a static method. Here's how you can do it: ```ts -@NgModule({ +export const appConfig: ApplicationConfig = { providers: [ // ... provideAbpCore( @@ -172,8 +166,7 @@ Here's how you can do it: }), ), ], -}) -export class AppModule {} +}; ``` In this code, `myDynamicLayouts` is the map of dynamic layouts you defined earlier. We pass this map to the `provideAbpCore` using the `withOptions` method. @@ -186,32 +179,33 @@ Here's how you can do it: // route.provider.ts import { eCustomLayout } from './custom-layout/custom-layout.provider'; import { RoutesService, eLayoutType } from '@abp/ng.core'; -import { APP_INITIALIZER } from '@angular/core'; +import { provideAppInitializer } from '@angular/core'; export const APP_ROUTE_PROVIDER = [ - { provide: APP_INITIALIZER, useFactory: configureRoutes, deps: [RoutesService], multi: true }, + provideAppInitializer(() => { + configureRoutes(); + }), ]; -function configureRoutes(routes: RoutesService) { - return () => { - routes.add([ - { - path: '/', - name: '::Menu:Home', - iconClass: 'fas fa-home', - order: 1, - layout: eLayoutType.application, - }, - { - path: '/dashboard', - name: '::Menu:Dashboard', - iconClass: 'fas fa-chart-line', - order: 2, - layout: eCustomLayout.key as eLayoutType, - requiredPolicy: 'MyProjectName.Dashboard.Host || MyProjectName.Dashboard.Tenant', - }, - ]); - }; +function configureRoutes() { + const routes = inject(RoutesService); + routes.add([ + { + path: '/', + name: '::Menu:Home', + iconClass: 'fas fa-home', + order: 1, + layout: eLayoutType.application, + }, + { + path: '/dashboard', + name: '::Menu:Dashboard', + iconClass: 'fas fa-chart-line', + order: 2, + layout: eCustomLayout.key as eLayoutType, + requiredPolicy: 'MyProjectName.Dashboard.Host || MyProjectName.Dashboard.Tenant', + }, + ]); } ``` @@ -288,10 +282,23 @@ Open the generated `routes.component.ts` in `src/app/routes` folder and replace ```js import { Component, HostBinding } from "@angular/core"; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; +import { LocalizationPipe, PermissionDirective } from "@abp/ng.core"; +import { EllipsisDirective } from '@abp/ng.theme.shared'; @Component({ selector: "app-routes", templateUrl: "routes.component.html", + imports: [ + CommonModule, + RouterModule, + NgbDropdownModule, + PermissionDirective, + EllipsisDirective, + LocalizationPipe, + ] }) export class RoutesComponent { @HostBinding("class.mx-auto") @@ -303,21 +310,6 @@ export class RoutesComponent { } ``` -Import the `SharedModule` to the `imports` array of `AppModule`: - -```js -// app.module.ts - -import { SharedModule } from './shared/shared.module'; - -@NgModule({ - imports: [ - //... - SharedModule - ] -)} -``` - Open the generated `routes.component.html` in `src/app/routes` folder and replace its content with the following: ```html @@ -482,8 +474,12 @@ import { LanguageInfo, NAVIGATE_TO_MANAGE_PROFILE, SessionStateService, + LocalizationPipe } from '@abp/ng.core'; import { Component, Inject } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; +import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import snq from 'snq'; @@ -491,6 +487,12 @@ import snq from 'snq'; @Component({ selector: 'app-nav-items', templateUrl: 'nav-items.component.html', + imports: [ + CommonModule, + FormsModule, + NgbDropdownModule, + LocalizationPipe + ] }) export class NavItemsComponent { currentUser$: Observable = this.configState.getOne$('currentUser'); @@ -549,21 +551,6 @@ export class NavItemsComponent { } ``` -Import the `SharedModule` to the `imports` array of `AppModule`: - -```js -// app.module.ts - -import { SharedModule } from './shared/shared.module'; - -@NgModule({ - imports: [ - //... - SharedModule - ] -)} -``` - Open the generated `nav-items.component.html` in `src/app/nav-items` folder and replace the content with the following: ```html