由于服务单例,我有一个可配置的Angular模块,该模块具有forRoot()
方法中提供的配置。
该模块在模块本身的外部公开了一个指令和一个组件,用于呈现模块的功能(对话框中的一种File Explorer)。
配置服务是这样的:
@Injectable()
export class FileManagerConfigService {
config: IFileManagerConfig;
private moduleConfiguration: IFileManagerConfig;
constructor(moduleConfiguration?: IFileManagerConfig) {
this.moduleConfiguration = { ...DEFAULT_FILE_MANAGER_CONFIG, ...moduleConfiguration };
this.config = { ...DEFAULT_FILE_MANAGER_CONFIG, ...moduleConfiguration };
}
/**
* Override the module configuration with a new one
* @param adHocConfiguration new plugin configuration
*/
mergeConfig(adHocConfiguration: Partial<IFileManagerConfig>) {
this.config = { ...DEFAULT_FILE_MANAGER_CONFIG, ...this.moduleConfiguration, ...adHocConfiguration };
}
/**
* returns the current configuration
*/
getConfig(): IFileManagerConfig {
return this.config;
}
/**
* Restore the plugin configuration to the module one.
*/
setDefault() {
this.config = this.moduleConfiguration;
}
}
在模块中,其实例如下:
public static forRoot(config?: Partial<IFileManagerConfig>): ModuleWithProviders {
const configurationServiceInstance = new FileManagerConfigService(moduleConfiguration);
// injecting configuration for the service!
return {
ngModule: FileManagerModule,
providers: [
FileManagerModalService,
FileManagerService,
{
provide: FileManagerConfigService,
useValue: configurationServiceInstance
}
]
};
我想知道是否有办法,还是这样做是一种好习惯,否则我必须更改所有方法,以分别在组件中使用@Input()装饰器和指令维护来覆盖服务配置为我提供当前配置的配置全局服务,因此我可以在模块的其他服务中使用它(避免对所有模块使用单个实例)。因此,在组件或指令中,我可以执行以下操作:
@Input() fileManagerOptions: Partial<IFileManagerConfig>;
ngAfterViewInit() {
if (this.fileManagerOptions) {
// merge della configurazione con la configurazione data
this.fmConfigService.mergeConfig(this.fileManagerOptions);
} else {
this.fmConfigService.setDefault();
}
}
因此,当我得到this.fmConfigService
时,即使指令和组件在同一外部组件中使用,我也可以确保将配置与@Input分开合并。