我现在正在开展一个非常大的项目,我们正努力让我们的代码尽可能模块化。我们有多个Angular应用程序,并且我们已经创建了一个单独的常用UI组件库和一个API套件,其中包含跨这些应用程序使用的公共服务。
我们在尝试构建需要使用服务的通用组件时遇到了问题。例如,我现在正在处理自动完成组件。该组件应该能够从远程源获取数据,并根据在组件的输入字段中输入的内容过滤结果。
对于一个实例,该实现很容易。我在自动完成组件的构造函数中注入自动完成服务,然后在父级上提供它。这使我可以灵活地在使用服务时更改服务的实现细节,同时仍然能够创建可与定义的接口一起使用的可重用组件。
例如:
我们要定义自动填充组件使用的界面的服务:
@Injectable()
export class AutocompleteService {
public url: string = 'my-api-default';
constructor(http: Http) {}
fetch(): any {
return this.http.get(this.url);
}
}
自动完成组件实现:
@Component({
selector: 'my-autocomplete',
templateUrl: 'my-autocomplete.component.html'
})
export class MyAutocompleteComponent {
constructor(private autocompleteService: AutocompleteService) {}
getData() {
return this.autocompleteService.fetch();
}
...autocomplete logic...
}
现在我可以定义一个实现自动完成服务的熊服务。我可以将熊服务连接到我的自动完成组件,所以我可以选择我的形式的熊物种。
@Injectable()
export class BearService {
public url: string = 'bear-url';
constructor(http: Http){}
fetch() {
return this.http.get(this.url);
}
}
接下来,我定义了使用我的自动完成组件的父级,并提供熊服务来获取我的熊种数据。
@Component({
selector: 'my-form-component',
template: `
<form>
<my-autocomplete [(ngModel)]="bear"></my-autocomplete>
<button type="submit">Submit</button>
</form>
`,
providers: [
{provide: AutocompleteService, useClass: BearService}
]
})
export class MyFormComponent {
...component logic...
}
到目前为止,这么好。
当我需要构建一个使用多个自动完成组件的大型表单时,我的问题就出现了。我的老板告诉我,我需要在这个表格上有三个自动填充区域,一个用于熊类,一个用于甜菜物种,一个用于太空堡垒加拉太卡。我的第一个想法是这样做:
我定义了服务实例:
@Injectable()
export class BeetsService {
public url: string = 'beets-url';
constructor(http: Http){}
fetch() {
return this.http.get(this.url);
}
}
@Injectable()
export class BattleStarGallacticaService {
public url: string = 'battlestar-gallactica';
constructor(http: Http){}
fetch() {
return this.http.get(this.url);
}
}
然后我更新父模板和提供者:
@Component({
selector: 'my-form-component',
template: `
<form>
<my-autocomplete [(ngModel)]="bear"></my-autocomplete>
<my-autocomplete [(ngModel)]="beet"></my-autocomplete>
<my-autocomplete [(ngModel)]="battleStarGallactica"></my-autocomplete>
<button type="submit">Submit</button>
</form>
`,
providers: [
{provide: AutocompleteService, useClass: BearService},
{provide: AutocompleteService, useClass: BeetService},
{provide: AutocompleteService, useClass: BattlestarGalacticaService},
]
})
export class MyFormComponent {
...component logic...
}
现在我怎么知道哪个自动完成组件使用哪个服务?
我知道我现在拥有的始终使用为AutocompleteService提供的最后一个提供程序,因为这是Angular DI框架的工作原理。
我也知道我不能在此使用多提供商,因为Angular仅为NG_VALIDATORS
和NG_ASYNC_VALIDATORS
定义了多提供商。
那么,有没有人知道如何解决我的问题?我不在乎 问题本身如何解决,但我仍然需要能够:
答案 0 :(得分:2)
我会将提供者移动到有选择地应用的指令
@Directive({
selector: 'my-autocomplete[bear]',
providers: [{ provide: AutoCompleteService, useClass: BearService}]
})
export class BearDirective {}
@Directive({
selector: 'my-autocomplete[battlestarGalactica]',
providers: [{ provide: AutoCompleteService, useClass: BattlestarGalacticaService}]
})
export class BattelstarGalacticaDirective{}
然后像
一样使用它<form>
<my-autocomplete bear [(ngModel)]="bear"></my-autocomplete>
<my-autocomplete bear [(ngModel)]="beet"></my-autocomplete>
<my-autocomplete battlestarGalactica [(ngModel)]="battleStarGallactica"></my-autocomplete>
<button type="submit">Submit</button>
</form>
并从MyFormComponent