标签: angular-dependency-injection

如何为从组件导入的模块设置config(或useValue)?

我们很清楚,有多种方法可以为导入的模块设置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

5
推荐指数
0
解决办法
406
查看次数

如何提供一个拥有自己的“factory”的“InjectionToken”?

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)

angular angular-dependency-injection

5
推荐指数
1
解决办法
4816
查看次数

@Injectable的语义(providedIn:'root')?

只是想确保我理解它的语义@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

4
推荐指数
1
解决办法
1299
查看次数

Angular - useExisting ngForm 可选

我需要将表单从父组件注入到子组件中,以便能够验证子组件输入,如下所示:

    <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)

谢谢你的时间!

angular angular-forms angular-dependency-injection

3
推荐指数
1
解决办法
1496
查看次数