我们很清楚,有多种方法可以为导入的模块设置config。我们有“ .forRoot()”,“ useValue”,“ useClass”,这些将在导入模块中使用。
例如,我们要使用ng2-currency-mask。直接从文档中的示例用法中,我们可以CurrencyMaskModule通过在导入模块(在本例中为AppModule)中进行设置来进行配置:
export const CustomCurrencyMaskConfig: CurrencyMaskConfig = {
align: "right",
allowNegative: true,
decimal: ",",
precision: 2,
prefix: "Module$ ",
suffix: "",
thousands: "."
};
@NgModule({
imports: [
...
CurrencyMaskModule
],
declarations: [...],
providers: [
{ provide: CURRENCY_MASK_CONFIG, useValue: CustomCurrencyMaskConfig }
],
bootstrap: [AppComponent]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
但是,如果要useValue动态设置config / (例如,“设置”页面),则必须在组件内部进行更改。现在,我使用以下直接在中编写的代码进行了测试AppComponent:
import { Component, OnInit, Inject } from '@angular/core';
import { CURRENCY_MASK_CONFIG, CurrencyMaskConfig } from 'ng2-currency-mask/src/currency-mask.config';
@Component({
selector: 'app-root', …Run Code Online (Sandbox Code Playgroud) dependency-injection typescript angular-module angular angular-dependency-injection
InjectionToken对于类型,请考虑以下因素Foo:
export const FOO = new InjectionToken<Foo>(
'foo token',
{ factory: () => new Foo() });
Run Code Online (Sandbox Code Playgroud)
现在假设我疯狂到想要 100% 的测试覆盖率。为此,我必须对这个小factory功能进行单元测试。
我正在考虑创建一个在我的测试中只有一个提供程序的注入器:
const inj = Injector.create({
providers: [{ provide: FOO }] // compiler error here
});
const foo = inj.get(FOO);
expect(foo).toBeTruthy();
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会失败并出现编译器错误,因为没有、或属性{ provide: FOO }的提供程序不是有效的。但是,当注入令牌带有自己的工厂时,为什么我必须定义其中之一呢?useValueuseFactoryuseExisting
当然,我还是尝试了所有选项:
useValue: FOO编译并运行,但似乎没有执行工厂方法useFactory: () => FOO, deps: []也编译并运行,但似乎也不执行工厂方法useExisting: FOO编译,但在运行时因循环依赖错误而失败有趣的是,的文档InjectionToken中提出了类似的场景,但它没有显示我正在寻找的注册:
const MY_SERVICE_TOKEN = new InjectionToken<MyService>('Manually constructed MyService', {
providedIn: …Run Code Online (Sandbox Code Playgroud) 只是想确保我理解它的语义@Injectable(providedIn: 'root').在Angular 6之前,如果我们从包含服务的NPM导入模块,我们将在我们的app模块中声明该模块,以便整个应用程序可以访问该服务.像这样的东西:
import { SomeNPModule } from '@ngx/SomeNPModule';
@NgModule({
imports: [
BrowserModule,
SomeNPModule
]
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)
现在我们可以注入SomeService模块提供的内容,因为我们已经导入了模块.使用Angular 6,因为我们正在使用服务本身,所以需要导入SomeNPModule到其中,并且当注释运行时,它会自动使注释容器中的服务可用吗?AppModule@Injectable(providedIn: 'rootroot
所以我们有了答案,但我认为它是部分完整的,因为如果我们想要配置服务,这通常是通过forRoot服务模块上的方法完成的......就像通过Router.因此,假设我们不想配置服务,我们需要做的只是注入它,但如果我们想要一个配置的服务,我们需要遵循这种Router模式.如果我在评论中犯了任何错误,请纠正我.
typescript angular-providers progressive-web-apps angular angular-dependency-injection
我需要将表单从父组件注入到子组件中,以便能够验证子组件输入,如下所示:
<form #formReference="ngForm">
<child-component></child-component>
<child-component></child-component>
<child-component></child-component>
<p>{{formReference.form.valid}}</p>
</form>
Run Code Online (Sandbox Code Playgroud)
现在我已经在子组件上添加了这个提供程序,使其使用父表单并且工作正常
@Component({
selector: 'app-child-component',
templateUrl: './child-component.component.html',
styleUrls: ['./child-component.component.scss'],
viewProviders: [ { provide: ControlContainer, useExisting: NgForm } ]
})
Run Code Online (Sandbox Code Playgroud)
但是,我仍然需要能够像以前一样在没有表单的情况下使用子组件。有没有办法让这个提供者可选?目前,如果在没有表单包装的情况下使用我的子组件,我会收到错误
ERROR NullInjectorError: R3InjectorError(CustomModule)[NgForm -> NgForm -> NgForm -> NgForm -> NgForm]
Run Code Online (Sandbox Code Playgroud)
谢谢你的时间!