각도 라이브러리 모듈이 추상 클래스를 사용하여 서비스 주입
Angular Component Library를 만들어 NPM을 통해(Nexus를 통해) 여러 유사 프로젝트에 배포했습니다.여기에는 다음이 포함됩니다.PageComponent
그것은 차례로 다음을 포함합니다.FooterComponent
그리고 aNavbarComponent
인NavbarComponent
버튼이 존재하며, 이 버튼은logout
기능.이 기능은 다음을 통해 제공됩니다.PageService
각 프로젝트의.이 목적을 위해 저는 다음을 만들었습니다.AbstractPageService
Angular Component 라이브러리(PageService
확장된AbstractPageService
).
처음에 저는 이것을 통해 해결했습니다.EventEmitter
하지만 내가 제공해야 했기 때문에.logout
각각의 새로운 페이지에 대한 기능, 나는 프로젝트당 하나의 서비스를 통해 이것을 해결하고 싶었습니다.나는 통과PageService
(프로젝트) 를 사용하여forRoot()
Angular Component Library 메서드입니다.
모든 것이 원하는 대로 작동하지만 더 나은 솔루션이 있는지 또는 솔루션이 그렇게 권장되는지 알고 싶으십니까?
이에 대한 해결책은 다음과 같습니다.
구성요소 Lib - 구성요소.module.ts
import {ModuleWithProviders, NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {RouterModule} from '@angular/router';
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
import {NavbarComponent} from './layout/navbar/navbar.component';
import {PageComponent} from './layout/page/page.component';
import {PageHeaderComponent} from './components/page-header/page-header.component';
// ... others ...
@NgModule({
imports: [
CommonModule,
RouterModule,
FontAwesomeModule
],
declarations: [
NavbarComponent,
PageComponent,
// ... others ...
],
exports: [
NavbarComponent,
PageComponent,
// ... others ...
]
})
export class ComponentsModule {
static forRoot(pageService): ModuleWithProviders {
return {
ngModule: ComponentsModule,
providers: [
{provide: 'PageService', useClass: pageService}
]
};
}
}
구성 요소 Lib - page.component.ts
import {Component, EventEmitter, HostBinding, Inject, Input, Output} from '@angular/core';
import {AbstractPageService} from '../../services/abstract-page.service';
@Component({
selector: 'dc-page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.scss']
})
export class PageComponent {
@HostBinding('class') styleClass = 'd-flex flex-column';
@Input() customStyleClass = null;
@Input() showLogoutButton = true;
// @Output() logoutButtonClick: EventEmitter<any> = new EventEmitter();
constructor(@Inject('PageService') protected pageService: AbstractPageService) {
}
logout(): void {
this.pageService.logout();
}
}
구성요소 Lib - 추상 페이지입니다.service.ts
import {Injectable} from '@angular/core';
@Injectable()
export abstract class AbstractPageService {
abstract logout(): void;
}
여기서 프로젝트에서의 용도는 다음과 같습니다.
프로젝트 - app.module.ts
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {AppComponent} from './app.component';
import {RouterModule, Routes} from '@angular/router';
import {FontAwesomeModule} from '@fortawesome/angular-fontawesome';
import {ComponentsModule} from 'components';
const appRoutes: Routes = [
{path: '', component: AppComponent},
// otherwise redirect to home
{path: '**', redirectTo: ''}
];
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
FontAwesomeModule,
RouterModule.forRoot(appRoutes),
ComponentsModule.forRoot(PageService),
],
providers: [
// {provide: 'PageService', useClass: PageService}
],
bootstrap: [AppComponent]
})
export class AppModule {
}
프로젝트 - 페이지.service.ts
import {Injectable} from '@angular/core';
import {AbstractPageService} from '../../../projects/components/src/lib/services/abstract-page.service';
@Injectable({
providedIn: 'root'
})
export class PageService extends AbstractPageService {
constructor() {
super();
}
logout() {
console.log('Ausloggen!');
}
}
이 접근 방식을 사용했지만 한 가지 문제에 부딪혔습니다.
라이브러리의 싱글톤 인스턴스가 응용 프로그램의 인스턴스와 다릅니다.여러 모듈(애플리케이션 모듈 및 라이브러리 모듈)에 제공되므로 각 모듈에 대해 새 인스턴스를 생성합니다.
결국 제가 하게 된 것은 서비스를 제공하는 것이었습니다.string
응용 프로그램 모듈에서:
// app.module.ts in the root application
providers: [
{
provide: 'PageService',
useClass: PageService
}
]
그런 다음 필요한 곳에 서비스를 주입합니다.@Inject()
// anywhere in the root application where the service is needed
constructor(@Inject('PageService') private pageService: PageService) {}
그런 다음 라이브러리에서 간단한 인터페이스를 만들었습니다.
export interface AbstractPageService {
logout(): void;
}
그러면, 나는 간단히 도서관에 서비스를 주입할 수 있습니다.Inject()
데코레이터 및 인터페이스를 사용하여 입력합니다(루트 응용 프로그램에서 인터페이스를 구현할 필요 없음).
// anywhere in the library where the service is needed
constructor(@Inject('PageService') private pageService: AbstractPageService) {}
이제 루트 애플리케이션과 라이브러리 모두 동일한 싱글톤 인스턴스를 사용합니다.PageService
루트 응용 프로그램에 제공된 대로.
싱글톤을 재사용하는 방법
애플리케이션 appModule.ts에서 제공합니다.
{ provide: 'currentCompanyService', useFactory: getCompanyServiceFactory, deps: [AppInitService]}
주입된 인스턴스만 반환하는 공장을 만듭니다.
export function getCompanyServiceFactory(appInitService: AppInitService): AppInitService {
return appInitService;
}
라이브러리 구성 요소에 주입
public CustomLibraryComponent {
private companyService: AppInitService;
constructor(@Inject('currentEnvironment') environment: any,
@Inject('currentCompanyService') companyService: AppInitService) {
this.environment = environment;
this.companyService = companyService;
}
}
수닐 싱이 말했듯이, 정상적인 추상 수업이 해결책입니다.@Injectable
).
export abstract class AbstractPageService {
abstract logout(): void;
}
저는 'useClass'가 아닌 'useValue'가 있어야 한다고 생각합니다.
export class ComponentsModule {
static forRoot(pageService): ModuleWithProviders {
return {
ngModule: ComponentsModule,
providers: [
{provide: 'PageService', useClass: pageService}
]
};
}
}
언급URL : https://stackoverflow.com/questions/51859038/angular-library-module-inject-service-with-abstract-class
'programing' 카테고리의 다른 글
"IN" 연산자가 오라클에서 LIKE 와일드카드(%)를 사용할 수 있습니까? (0) | 2023.06.17 |
---|---|
Oracle SQL에 "존재하지 않는 경우 create sequence..."와 같은 것이 있습니까? (0) | 2023.06.17 |
로컬 보석을 설치하려면 어떻게 해야 합니까? (0) | 2023.06.17 |
Oracle SQL - NULL 값이 있는 max() (0) | 2023.06.17 |
SQL: 사용 가능한 모든 테이블에서 모든 데이터 삭제 (0) | 2023.06.17 |