【发布时间】:2021-10-04 05:58:24
【问题描述】:
我有一个 BaseComponent 和其他扩展它的组件,例如 WidgetComponent。
我使用ComponentFactoryResolver动态创建WidgetComponents。
BaseComponent 负责发出 http 请求,因此扩展组件可以通过包含 Observable 的公共属性访问响应。它使用SomeService 服务发出这些请求。
BaseComponent 在延迟加载模块中声明。
问题是,每次BaseComponent 发出请求时,每个扩展类都会收到响应,因为我认为我没有使用服务的唯一实例。
所以我的问题是,如何在每次动态创建 WidgetComponent 时使用不同的 SomeService 实例?
这是我的设置:
// BaseComponent.ts
import { InjectorService } from '@services/utils/injector.service';
import { SomeService } from '@services/some.service';
@Component({
selector: 'base-widget',
templateUrl: './base-widget.component.html'
})
export class BaseWidgetComponent {
response$!: Observable<any>;
someService: SomeService;
constructor() {
const injector = InjectorService.getInjector();
this.someService = injector.get(SomeService);
this.response$ = this.someService.getData();
}
}
// 小部件组件
@Component({
selector: 'widget',
templateUrl: './widget.component.html'
})
export class WidgetComponent extends BaseWidget implements OnInit {
ngOnInit() {
this.response$.subscribe(console.log);
}
}
// 一些服务
@Injectable({ providedIn: 'root' }) // I think this is not the correct way of providing it.
export class SomeService {
constructor(private http: HttpClient) {}
getData() {
return this.http.get('url');
}
}
// 注入器服务
import { Injector } from '@angular/core';
export class InjectorService {
private static injector: Injector;
static setInjector(injector: Injector) {
InjectorService.injector = injector;
}
static getInjector(): Injector {
return InjectorService.injector;
}
}
// main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { InjectorService } from '@services/utils/injector.service';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
(async () => {
try {
const moduleRef = await platformBrowserDynamic().bootstrapModule(AppModule);
InjectorService.setInjector(moduleRef.injector);
} catch (err) {
console.error(err);
}
})();
【问题讨论】:
-
通过将服务添加到组件的
providers数组中,组件可以拥有自己唯一的服务实例。请参阅文档here。 “在组件中提供服务将服务仅限于该组件及其后代。同一模块中的其他组件无法访问它。” -
感谢您的回答。那么在这种情况下,组件的每个新实例都会有自己独特的服务实例?另外,我忘了提到一个重要的细节。该组件在延迟加载的模块中声明。我尝试在组件中提供服务,但出现“空注入”错误。
-
这里的问题是您尝试使用继承,而 Angular 更适合与组合一起使用。长话短说,为什么不将 BaseWidgetComponent 中的代码导出到另一个 Service 中? (并使用 Angular DI 在您的组件中获取此服务)
标签: angular dependency-injection angular-dynamic-components